如何获取Pac4j/Shiro使用的当前KeycloakOidcConfiguration实例
从数据库动态加载Keycloak配置到Pac4j/Shiro
你之前修改shiro-web.ini的方式无效,核心原因是:Shiro启动时已经根据原始ini文件创建了KeycloakOidcConfiguration实例,你修改的只是内存中的Ini对象副本,不会同步到已初始化的实际配置实例上,因此才会出现realm cannot be blank的错误。
以下是两种可行的解决方案:
方案一:获取已初始化的配置实例并修改
在应用完成Shiro初始化后,通过SecurityManager的组件链获取到实际在用的KeycloakOidcConfiguration实例,再从数据库加载配置赋值:
// 确保应用已完成Shiro初始化后执行 DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) SecurityUtils.getSecurityManager(); Pac4jSubjectFactory subjectFactory = (Pac4jSubjectFactory) securityManager.getSubjectFactory(); Pac4jSecurityManager pac4jSecurityManager = subjectFactory.getPac4jSecurityManager(); // 根据你在ini中配置的客户端ID,找到对应的OidcClient实例 OidcClient oidcClient = (OidcClient) pac4jSecurityManager.getClients().findClient("your-oidc-client-id"); KeycloakOidcConfiguration oidcConfig = (KeycloakOidcConfiguration) oidcClient.getConfiguration(); // 从数据库加载配置并设置 oidcConfig.setRealm(keycloakApplicationProvider.getRealm()); oidcConfig.setClientId(keycloakApplicationProvider.getClientId()); oidcConfig.setClientSecret(keycloakApplicationProvider.getClientSecret()); oidcConfig.setDiscoveryURI(keycloakApplicationProvider.getDiscoveryURI()); // 其他必要配置项同理设置
方案二:自定义Factory在初始化时加载数据库配置
直接在Shiro初始化阶段,通过自定义Factory创建KeycloakOidcConfiguration实例,从数据库读取配置完成初始化:
- 修改
shiro.ini配置,指定自定义Factory:
#Keycloack authcConfig = com.yourpackage.CustomKeycloakConfigFactory
- 实现自定义Factory类:
public class CustomKeycloakConfigFactory implements Factory<KeycloakOidcConfiguration> { // 注入数据库查询依赖(可通过Shiro依赖注入或Spring容器获取) private final KeycloakApplicationProvider keycloakApplicationProvider; public CustomKeycloakConfigFactory(KeycloakApplicationProvider keycloakApplicationProvider) { this.keycloakApplicationProvider = keycloakApplicationProvider; } @Override public KeycloakOidcConfiguration getInstance() { KeycloakOidcConfiguration config = new KeycloakOidcConfiguration(); // 从数据库加载所有必要配置 config.setRealm(keycloakApplicationProvider.getRealm()); config.setClientId(keycloakApplicationProvider.getClientId()); config.setClientSecret(keycloakApplicationProvider.getClientSecret()); config.setDiscoveryURI(keycloakApplicationProvider.getDiscoveryURI()); // 补充其他必填配置 return config; } }
这种方式能确保Shiro初始化时就使用数据库中的配置,从根源避免后续修改不同步的问题。
内容的提问来源于stack exchange,提问作者vished2000
相关产品推荐
相关产品推荐

