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

在EJB模块中访问Java Security API的方案咨询(基于WildFly与Soteria)

嘿,针对你在WildFly里的EJB模块访问Java Security API的需求,结合你已经在WAR包里用了Soteria的情况,我给你整理了具体的实现步骤:

1. 给EJB模块添加Soteria依赖

首先,你的EJB JAR模块需要引入和WAR包一致的Soteria依赖,这样编译时才能获取到Java Security API的相关类。在EJB的pom.xml里加入这段配置:

<dependency>
    <groupId>org.glassfish.soteria</groupId>
    <artifactId>javax.security.enterprise</artifactId>
    <version>1.0</version>
    <!-- 建议用provided scope,因为最新版WildFly运行时已经自带Soteria,避免依赖冲突 -->
    <scope>provided</scope>
</dependency>

如果你的WildFly版本没有内置Soteria(比如较老版本),可以去掉<scope>provided</scope>,让依赖打包进EJB模块。

2. 在EJB中注入并使用Security API

Soteria基于CDI实现,所以你可以直接在EJB里注入Java Security API的核心组件,比如SecurityContext、IdentityStoreHandler等。这里给你举几个常用场景的代码示例:

示例1:获取当前调用者的自定义Principal

假设你在WAR里定义了EmployeePrincipal,可以在EJB里这样获取:

import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.security.enterprise.SecurityContext;
import javax.annotation.security.RolesAllowed;

@Stateless
public class EmployeeService {

    @Inject
    private SecurityContext securityContext;

    // 限制只有employee角色的用户能调用这个方法
    @RolesAllowed("employee")
    public String getCurrentEmployeeId() {
        // 从安全上下文获取自定义的EmployeePrincipal
        EmployeePrincipal employeePrincipal = securityContext.getPrincipalsByType(EmployeePrincipal.class)
                .findFirst()
                .orElseThrow(() -> new IllegalStateException("当前用户不是员工身份"));
        return employeePrincipal.getEmployeeId();
    }
}

示例2:检查当前用户是否登录

@PermitAll
public boolean isAuthenticated() {
    Principal caller = securityContext.getCallerPrincipal();
    return caller != null && !"anonymous".equals(caller.getName());
}
3. 确保自定义Principal的可访问性

因为你的WAR和EJB是独立模块,要让EJB能识别你定义的UserPrincipal、EmployeePrincipal等自定义类,最好把这些Principal类抽出来放到一个共享的JAR模块里,然后让WAR和EJB都依赖这个共享模块。这样可以避免类加载问题,比如ClassNotFoundException。

4. 必要的配置检查
  • 确保EJB模块里存在META-INF/beans.xml文件(即使是空文件也可以),因为CDI需要这个文件来启用依赖注入功能,这样@Inject才能正常工作。
  • 检查WildFly的配置(standalone.xml或domain.xml),确保security子系统已经启用,最新版WildFly默认是开启的,不需要额外配置。
  • 当WAR调用EJB时,WildFly默认会自动传递安全上下文,所以调用者的身份信息会被带到EJB中,不需要额外配置跨模块的安全传递(只要EJB方法有正确的安全注解,比如@RolesAllowed)。
注意事项
  • 自定义Principal类必须实现java.security.Principal接口,并且正确重写equals()和hashCode()方法,这样SecurityContext才能正确匹配和返回这些Principal。
  • 如果你的EJB是远程调用的,确保WildFly的远程安全配置没有禁用身份传递,默认情况下远程调用也是会传递安全上下文的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:25:27