Wildfly 26中EJB用@SecurityDomain遇WFLYCTL0180依赖缺失问题
我们的应用包含多个标注了@SecurityDomain("our-ws")的Web服务(也尝试在jboss-web.xml中配置该属性),示例代码如下:
@Stateless @Interceptors(OurTransactionInterceptor.class) @WebService(targetNamespace = "...", portName = "AddStuff", serviceName = "AddStuffService") @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.WRAPPED) @WebContext(authMethod = "BASIC", contextRoot = "/service", urlPattern = "/AddStuffService") @SecurityDomain("our-ws") public class AddStuffService { ... }
升级至Wildfly 26并采用Elytron安全框架(参考《WildFly Elytron Security》文档4.1.3节)后,启动时出现错误:
13 Jan 2023 11:26:01,763 ERROR [management-operation Controller Boot Thread] WFLYCTL0013: Operation ("deploy") failed - address: ([("deployment" => "service.war")]) - failure description: { "WFLYCTL0412: Required services that are not installed:" => ["jboss.security.security-domain.our-ws"], "WFLYCTL0180: Services with missing/unavailable dependencies" => ["jboss.deployment.unit.\"service.war\".component.AddStuffService.CREATE is missing [jboss.security.security-domain.our-ws]"] }
已在standalone.xml的<subsystem xmlns="urn:wildfly:elytron:15.1"...>节点下完成以下配置:
- 配置了名为
ourDS的数据源(未展示),并基于它创建JDBC Realm:
<jdbc-realm name="jdbc"> <principal-query sql="SELECT password FROM CFG_WS_USERS_T WHERE username=?" data-source="evercoreDS"> <clear-password-mapper password-index="1"/> </principal-query> <principal-query sql="SELECT roles from CFG_WS_ROLES_T r join CFG_WS_USERS_T u on u.WS_USERS_PK=r.WS_USERS_FK where u.username=?" data-source="ourDS"> <attribute-mapping> <attribute to="roles" index="1"/> </attribute-mapping> </principal-query> </jdbc-realm>
- 配置了对应Web服务的Security Domain:
<security-domain name="our-ws" default-realm="jdbc" permission-mapper="default-permission-mapper"> <realm name="jdbc" role-decoder="groups-to-roles"/> </security-domain>
补充说明:还按照文档配置了HTTP认证工厂和应用安全域:
<http-authentication-factory name="our-ws-http-auth" security-domain="our-ws" http-server-mechanism-factory="global"> <mechanism-configuration> <mechanism mechanism-name="BASIC"> <mechanism-realm realm-name="our-ws"/> </mechanism> </mechanism-configuration> </http-authentication-factory> <application-security-domains> <application-security-domain name="defaultASD" security-domain="ApplicationDomain"/> <application-security-domain name="our-ws-appsecurity-domain" http-authentication-factory="our-ws-http-auth"/> </application-security-domains>
(对mechanism-realm realm-name="our-ws"存在困惑,因为our-ws是security-domain而非security-realm,尝试改用jdbc security-realm后错误依旧)
疑问:为何jboss.security.security-domain.our-ws未被加载?如何让@SecurityDomain注解(或jboss-web.xml中的security-domain标签)关联到Elytron的配置?
问题核心是:Elytron的Security Domain和遗留的PicketBox安全域是两套独立的服务体系,@SecurityDomain默认会查找PicketBox的安全域服务(即jboss.security.security-domain.xxx),而你配置的是Elytron的安全域,所以找不到对应服务。
解决步骤如下:
1. 对齐应用安全域名称
修改application-security-domains配置,让应用安全域的名称和@SecurityDomain指定的名称完全匹配,这样应用就能关联到Elytron的安全域:
<application-security-domains> <application-security-domain name="our-ws" security-domain="our-ws"/> </application-security-domains>
2. 修正mechanism-realm配置
mechanism-realm指定的是Realm的名称,不是Security Domain的名称。你配置的JDBC Realm名称是jdbc,所以调整为:
<mechanism mechanism-name="BASIC"> <mechanism-realm realm-name="jdbc"/> </mechanism>
3. 禁用遗留安全子系统(可选)
如果应用不再需要使用PicketBox框架,可以直接在standalone.xml中移除<subsystem xmlns="urn:jboss:domain:security:2.0"/>相关配置,避免服务混淆。
4. 验证安全域加载
启动Wildfly时,检查日志中是否存在WFLYELY00001: Security domain 'our-ws' is ready的日志,确认Elytron安全域已成功加载。
5. jboss-web.xml适配(若使用)
如果通过jboss-web.xml配置安全域,需添加elytron-enabled="true"属性明确指定使用Elytron:
<jboss-web> <security-domain>our-ws</security-domain> <elytron-enabled>true</elytron-enabled> </jboss-web>
内容的提问来源于stack exchange,提问作者mconner

