You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WildFly 35多模块EAR部署报错:SecurityDomain已关联ClassLoader

问题:EAR中单个WAR配置Keycloak认证在WildFly 35报错(ELY01148)

问题背景

我有一个包含至少2个WAR的EAR包:其中一个无需任何认证,另一个需通过Keycloak实现认证,认证配置仅通过针对该WAR的overlay文件实现。该配置在WildFly 26及之前版本可正常运行,升级至Jakarta EE体系的WildFly 35后,部署时触发报错。

报错日志

ttp-wf | "jboss.deployment.subunit."test-ear-2024.3.0-SNAPSHOT.ear"."test-web-2024.3.0-SNAPSHOT.war".undertow-deployment.UndertowDeploymentInfoService" => "Failed to start service
ttp-wf | Caused by: java.lang.IllegalStateException: ELY01148: A SecurityDomain has already been associated with the specified ClassLoader"

当前配置

Overlay的web.xml片段

<login-config>
    <auth-method>OIDC</auth-method>
</login-config>
...
<security-constraint>
        <display-name>security-domain</display-name>
        <web-resource-collection>
            <web-resource-name>security-domain</web-resource-name>
            <url-pattern>/html/internal/admin/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>role.admin</role-name>
        </auth-constraint>
    </security-constraint>

JBoss CLI配置命令

deployment-overlay add \
        --name=configKeycloakAuth \
        --content=/WEB-INF/web.xml=/entrypoint-wildfly-cli/config_oidc_web.xml \
        --deployments=config-web-*.war \
        --redeploy-affected
    set configVersion=2024.1.0
    /subsystem=elytron-oidc-client/secure-deployment=config-web-$configVersion.war:add( \
        provider-url=$ttpWebKeycloakBaseUrl/realms/$ttpWebKeycloakRealm, \
        client-id=$ttpWebKeycloakClientId, \
        ssl-required=$ttpWebKeycloakSslRequired, \
        confidential-port=$ttpWebKeycloakConfidentialPort, \
        use-resource-role-mappings=$ttpWebKeycloakUseResourceRoleMappings \
    )

环境限制

  • EAR必须保持ear-subdeployments-isolated=false配置,子部署类加载器共享
  • 无需认证的WAR的web.xml未声明security-domain,尝试设置security-domain=none不被允许
  • 当前使用WildFly 35,DEBUG日志无额外有效信息

解决方案

核心原因

WildFly 26之后的Jakarta EE版本中,当EAR子部署类加载器共享(ear-subdeployments-isolated=false)时,一旦某个WAR绑定了SecurityDomain,类加载器会被标记为已关联安全域,其他WAR无法再调整安全域配置,即使是设置为无安全域也会触发冲突。

调整方案

  1. 为需要认证的WAR单独指定安全域
    在overlay的web.xml中显式指定安全域名称,避免使用默认安全域导致全局类加载器冲突:

    <login-config>
        <auth-method>OIDC</auth-method>
        <security-domain>keycloak-web-security</security-domain>
    </login-config>
    

    同时更新CLI命令,创建独立的安全域并关联到该WAR:

    /subsystem=elytron/security-domain=keycloak-web-security:add(
        realms=[{realm-name=keycloak-oidc-realm}],
        default-realm=keycloak-oidc-realm,
        permission-mapper=default-permission-mapper
    )
    /subsystem=elytron-oidc-client/realm=keycloak-oidc-realm:add(
        provider-url=$ttpWebKeycloakBaseUrl/realms/$ttpWebKeycloakRealm,
        client-id=$ttpWebKeycloakClientId,
        ssl-required=$ttpWebKeycloakSslRequired
    )
    /subsystem=elytron-oidc-client/secure-deployment=config-web-$configVersion.war:add(
        security-domain=keycloak-web-security,
        use-resource-role-mappings=$ttpWebKeycloakUseResourceRoleMappings
    )
    
  2. 为无需认证的WAR添加显式无安全域声明
    通过jboss-web.xml为无认证WAR添加空的安全域标签,明确告知容器该WAR不使用安全域:

    <jboss-web>
        <security-domain/>
    </jboss-web>
    

    此配置可避免容器自动尝试关联默认安全域,减少类加载器冲突概率。

  3. 调整部署顺序(辅助措施)
    先部署无需认证的WAR,再部署需要认证的WAR,降低类加载器初始化阶段的冲突概率,此方法仅作为辅助,核心解决依赖前两项配置。

验证要点

  • 确保每个WAR的安全域配置完全独立,共享类加载器下无互相覆盖
  • 检查WildFly Elytron子系统配置,确认无全局默认安全域自动绑定到所有Web部署

内容的提问来源于stack exchange,提问作者peatle_pp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 16:53:10