7.10. 使用 Jakarta EE
如果您正确设置了 META-INF/services
文件,则用户存储提供程序可以封装在任何 Jakarta EE 组件中。例如,如果您的供应商需要使用第三方库,您可以将供应商打包在 EAR 中,并将这些第三方库存储在 EAR/ 目录的 lib/
目录中。另请注意,提供程序 JAR 可以使用 jboss-deployment-structure.xml
文件,该文件 EJB、WARS 和 EARs 可在 JBoss EAP 环境中使用。有关此文件的详情,请查看 JBoss EAP 文档。它允许您在其他精细操作中拉取外部依赖项。
提供程序实施需要是纯 java 对象。但我们目前还支持将 UserStorageProvider
类实施为有状态 EJB。如果要使用 JPA 连接到关系存储,这尤其有用。这是实现它的方式:
@Stateful @Local(EjbExampleUserStorageProvider.class) public class EjbExampleUserStorageProvider implements UserStorageProvider, UserLookupProvider, UserRegistrationProvider, UserQueryProvider, CredentialInputUpdater, CredentialInputValidator, OnUserCache { @PersistenceContext protected EntityManager em; protected ComponentModel model; protected KeycloakSession session; public void setModel(ComponentModel model) { this.model = model; } public void setSession(KeycloakSession session) { this.session = session; } @Remove @Override public void close() { } ... }
您必须定义 @Local
注释并指定您的提供程序类。如果没有这样做,EJB 将不会正确代理用户,您的供应商将无法正常工作。
您必须将 @Remove
注释放在提供程序的 close ()
方法上。如果没有,则有状态的 bean 将不会被清理,您最终可能会看到错误消息。
对于 UserStorageProvider
,需要是普通 Java 对象。您工厂类在其 create ()方法中对 Stateful EJB 执行 JNDI 查找。
public class EjbExampleUserStorageProviderFactory implements UserStorageProviderFactory<EjbExampleUserStorageProvider> { @Override public EjbExampleUserStorageProvider create(KeycloakSession session, ComponentModel model) { try { InitialContext ctx = new InitialContext(); EjbExampleUserStorageProvider provider = (EjbExampleUserStorageProvider)ctx.lookup( "java:global/user-storage-jpa-example/" + EjbExampleUserStorageProvider.class.getSimpleName()); provider.setModel(model); provider.setSession(session); return provider; } catch (Exception e) { throw new RuntimeException(e); } }
本例还假定您已在与提供程序相同的 JAR 中定义 JPA 部署。这意味着 persistent .xml
文件以及任何 JPA @Entity
类。
使用 JPA 时,任何其他数据源必须是 XA 数据源。Red Hat Single Sign-On 数据源不是 XA 数据源。如果您在同一事务中与两个或多个非XA 数据源交互,服务器会返回错误消息。单个事务中只允许一个非XA 资源。有关部署 XA 数据源的详情,请参阅 JBoss EAP 手册。
不支持 CDI。