如何将PicketBox LdapLoginModule迁移至Elytron?迁移后遇登录模块配置错误
问题背景
原有系统基于JBoss LdapLoginModule实现LDAP认证,创建了名为"login"的JAAS安全域。当JMS请求传入时,应用通过javax.security.auth.login.LoginContext查找该安全域,结合CallbackHandler处理用户提交的用户名/密码完成登录。迁移到Elytron配置后,触发登录时出现No LoginModules configured for login错误。
旧JAAS安全域配置
<security-domain name="login" cache-type="default"> <authentication> <login-module code="org.jboss.security.auth.spi.LdapLoginModule" flag="required"> <module-option name="java.naming.provider.url" value="${java.naming.provider.url}"/> <module-option name="principalDNPrefix" value="${principalDNPrefix}"/> <module-option name="principalDNSuffix" value="${principalDNSuffix}"/> <module-option name="com.sun.jndi.ldap.connect.timeout" value="${ldap.connect.timeout}"/> </login-module> </authentication> </security-domain>
迁移后的Elytron配置
安全域与Realm配置
<security-realms> <ldap-realm name="ldapRealm" dir-context="ldapDirContext" direct-verification="true" allow-blank-password="true"> <identity-mapping rdn-identifier="uid" search-base-dn="ou=company,dc=compauth,dc=comp,dc=de" /> </ldap-realm> <caching-realm name="cached-ldap" realm="ldapRealm"/> </security-realms>
目录上下文配置
<dir-contexts> <dir-context name="ldapDirContext" url="${java.naming.provider.url}" authentication-level="none"> <properties> <property name="com.sun.jndi.ldap.connect.timeout" value="${ldap.connect.timeout}"/> </properties> </dir-context> </dir-contexts>
Elytron安全域配置
<security-domains> <security-domain name="login" default-realm="cached-ldap" permission-mapper="default-permission-mapper"> <realm name="cached-ldap" role-decoder="groups-to-roles"/> </security-domain> </security-domains>
错误日志
WARN [org.security.login.LoginServiceAbstract] (loginJmsContainer-2) LoginServiceBean.login exception occured : javax.security.auth.login.LoginException: No LoginModules configured for login at javax.security.auth.login.LoginContext.init(LoginContext.java:264) at javax.security.auth.login.LoginContext.<init>(LoginContext.java:417) at gts.common.refdata.core.platform.security.login.LoginServiceAbstract.login(LoginServiceAbstract.java:83) at gts.common.refdata.core.platform.security.login.LoginServiceAbstract.login(LoginServiceAbstract.java:68) ...
解决方案
核心原因
Elytron安全域与传统JAAS安全域是两套独立体系,原有代码通过LoginContext调用的是JAAS配置,但当前仅配置了Elytron安全域,未建立Elytron到JAAS的桥接,导致LoginContext找不到对应LoginModule配置。
具体修复步骤
添加Elytron到JAAS的桥接配置
新增认证配置、认证工厂,并通过jaas-authentication-factory将Elytron安全域映射到JAAS的"login"条目:<authentication-configurations> <authentication-configuration name="ldap-auth-config" realm="cached-ldap" /> </authentication-configurations> <authentication-factories> <authentication-factory name="ldap-auth-factory" authentication-configuration="ldap-auth-config" security-domain="login" /> </authentication-factories> <jaas-authentication-factories> <jaas-authentication-factory name="login-jaas-factory" authentication-factory="ldap-auth-factory" module-name="login" /> </jaas-authentication-factories>验证用户DN映射逻辑
原有LdapLoginModule通过principalDNPrefix+用户名+principalDNSuffix拼接DN,当前Elytron配置的rdn-identifier="uid"和search-base-dn="ou=company,dc=compauth,dc=comp,dc=de"与原有逻辑匹配,无需调整。确认目录上下文配置合理性
dir-context的authentication-level="none"搭配ldap-realm的direct-verification="true",符合原有直接用用户凭证绑定LDAP的认证逻辑,配置正确。检查配置顺序与命名空间
确保配置顺序为:dir-contexts→security-realms→security-domains→authentication-configurations→authentication-factories→jaas-authentication-factories,且所有配置在Elytron命名空间(如urn:wildfly:elytron:1.0)下。
验证修复
重启应用服务器后触发JMS登录请求,确认LoginContext可找到"login"对应的LoginModule(由Elytron桥接提供),认证流程正常执行。
内容的提问来源于stack exchange,提问作者codemonkey

