Configuration
Wildfly Standalone.xml - 從 elytron 憑證儲存向 KeyCloak SPI 傳遞秘密
我正在將 KeyCloak v15 (WildFly v23) 密碼從舊保險庫遷移到 elytron 憑證儲存。它適用於標準案例。在
standalone.xml
中,我有/server/extensions/extension
:<extension module="org.wildfly.extension.elytron"/>
/server/profile/subsystem
:<subsystem xmlns="urn:wildfly:elytron:13.0" final-providers="elytron" disallowed-providers="OracleUcrypto"> <providers> <provider-loader name="elytron" module="org.wildfly.security.elytron"/> </providers> <audit-logging> <file-audit-log name="local-audit" path="audit-log.log" relative-to="jboss.server.log.dir" format="JSON"/> </audit-logging> <credential-stores> <credential-store name="credStore" location="/data/credStore.jceks"> <implementation-properties> <property name="keyStoreType" value="JCEKS"/> </implementation-properties> <credential-reference clear-text="MASK-123456789;salt123;42"/> </credential-store> </credential-stores> </subsystem>
我使用以下方式訪問密碼
/server/profile/subsystem[@xmlns="urn:jboss:domain:jgroups:8.0"]/stacks/stack[@name="tcp"]/auth-protocol/digest-token/shared-secret-reference
:<shared-secret-reference store="credStore" alias="myBlock::mySecret"/>
但是,我需要將一個秘密傳遞給屬性中的 SPI。知道怎麼做嗎?這是舊的保險庫方式:
/server/system-properties/property
:<property name="secret" value="${VAULT::myBlock::mySecret::1}"/>
/server/profile/subsystem[@xmlns="urn:jboss:domain:keycloak-server:1.1"]/spi
:<spi name="mySpi"> <provider name="file" enabled="true"> <properties> <property name="password" value="${secret}"/> </properties> </provider> </spi>
我不得不重寫我們的 SPI 來讀取 Elytron 憑證儲存內容:
import org.jboss.as.server.CurrentServiceContainer; import org.jboss.msc.service.ServiceController; import org.jboss.msc.service.ServiceName; import org.jboss.msc.service.ServiceRegistry; import org.wildfly.security.credential.PasswordCredential; import org.wildfly.security.credential.store.CredentialStore; import org.wildfly.security.credential.store.CredentialStoreException; import org.wildfly.security.password.Password; import org.wildfly.security.password.interfaces.ClearPassword;
private static String getClientSecret(String credentialStore, String secretAlias) { final ServiceName SERVICE_NAME_CRED_STORE = ServiceName.of("org", "wildfly", "security", "credential-store"); final ServiceName sn = ServiceName.of(SERVICE_NAME_CRED_STORE, credentialStore); final ServiceRegistry registry = CurrentServiceContainer.getServiceContainer(); final ServiceController<?> credStoreService = registry.getService(sn); final CredentialStore cs = (CredentialStore) credStoreService.getValue(); // if (!cs.exists(secretAlias, PasswordCredential.class)) { // throw new CredentialStoreException("Alias " + secretAlias + " not found in credential store."); // } final Password password; try { password = cs.retrieve(secretAlias, PasswordCredential.class).getPassword(); } catch (CredentialStoreException e) { e.printStackTrace(); return null; } if (!(password instanceof ClearPassword)) { throw new ClassCastException("Password is not of type ClearPassword"); } return new String(((ClearPassword) password).getPassword()); }
我發現了兩種可能性:
- 重寫 SPI 以直接從 Java 中的 Elytron 憑證儲存中檢索秘密
- 預先設置環境變數 (
export SECRET="$(secret-getter-script)"
) 並使用變數 instandalone.xml
:<spi name="mySpi"> <provider name="file" enabled="true"> <properties> <property name="password" value="${env.SECRET}"/> </properties> </provider> </spi>