Wildfly24升级至25后报org/jboss/security/RunAs类找不到错误如何解决
问题原因
WildFly 25版本起正式废弃了基于org.jboss.security的遗留安全框架,默认启用Elytron作为唯一安全实现,原遗留安全相关的类默认不会对部署应用暴露,所以会触发NoClassDefFoundError。你单独添加security模块的extension不会自动把类暴露给应用,因此配置后问题无法解决。
解决方案
方案1:临时兼容遗留代码(不修改业务逻辑)
该方案仅作为过渡使用,官方不推荐长期依赖,后续版本会完全移除遗留安全模块:
- 保留原有业务代码不变,在你的应用部署包的
WEB-INF(war包场景)或者META-INF(ear/ejb包场景)目录下添加jboss-deployment-structure.xml配置,显式声明依赖遗留安全模块:
<jboss-deployment-structure> <deployment> <dependencies> <module name="org.jboss.security" export="true"/> <module name="org.picketbox" optional="false"/> </dependencies> </deployment> </jboss-deployment-structure>
如果是EAR格式的部署包,需要为对应的war/ejb子模块单独声明依赖:
<jboss-deployment-structure> <sub-deployment name="你的业务模块名称.war"> <dependencies> <module name="org.jboss.security" export="true"/> <module name="org.picketbox" optional="false"/> </dependencies> </sub-deployment> </jboss-deployment-structure>
- 确认
standalone.xml中除了<extension module="org.jboss.as.security"/>外,还保留了legacy安全子系统的完整配置,即包含<subsystem xmlns="urn:jboss:domain:security:2.0">相关节点。
方案2:迁移到Elytron标准实现(官方推荐)
原有功能可以直接用Elytron的SecurityIdentityAPI实现安全上下文传播,不需要依赖任何遗留的RunAs类,也不需要额外的standalone.xml特殊配置,替换后的代码示例如下:
import org.wildfly.security.auth.server.SecurityDomain; import org.wildfly.security.auth.server.SecurityIdentity; import java.security.Principal; import java.util.HashSet; import java.util.Set; // 原有业务逻辑段 Set<String> roleSet = getRoles() == null ? new HashSet<>() : getRoles(); String currentPrincipal = roleSet.isEmpty() ? "anonymous" : getUser(); // 获取当前线程绑定的安全域 SecurityDomain currentDomain = SecurityDomain.getCurrent(); // 构建自定义安全身份 SecurityIdentity runAsIdentity = currentDomain.createAdHocIdentity((Principal) () -> currentPrincipal); // 给身份绑定对应角色 for (String role : roleSet) { runAsIdentity = runAsIdentity.withRole(role); } // 保存原有上下文,执行完成后恢复 SecurityIdentity originalIdentity = currentDomain.getCurrentSecurityIdentity(); try { runAsIdentity.runAs(() -> { // 此处放置你需要执行的业务逻辑(比如调用EJB方法),安全上下文会自动传播到EJB层 yourBusinessMethod(); return null; }); } finally { currentDomain.getSecurityContext().setSecurityIdentity(originalIdentity); }
该实现完全兼容WildFly 25及所有后续版本,不存在后续升级兼容问题。
内容的提问来源于stack exchange,提问作者Karthic
相关产品推荐
相关产品推荐

