java - JAX-RS + EJB,ejb 内的 SecurityContext 为 null,在 WildFly 10.1 上

标签 java security ejb jax-rs wildfly

我正在第一次开发一个 JavaEE 应用程序(尝试..)使用 ejb 安全功能。 我正在使用 WildFly 10.1。 我创建了一个 Jdbc 安全域并配置了基于表单的登录。 Web方法和url路径的访问及登录工作权限(防止未授权访问,登录后授权访问)。

我有一组实现 (Jax-RS) REST 接口(interface)的 bean,还有一组实现应用程序业务逻辑的 ejb 无状态 bean。

这些是 jboss-web.xml 和 web.xml 的片段:

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

web.xml:

<security-constraint>
    <web-resource-collection>
        <url-pattern>/api/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>administrator</role-name>
        <role-name>operator</role-name>
        <role-name>user</role-name>
    </auth-constraint>
</security-constraint>
<login-config><!-- 3 -->
    <auth-method>FORM</auth-method>
    <realm-name>myRealm</realm-name>
    <form-login-config>
    <form-login-page>/public/login.html</form-login-page>
    <form-error-page>/public/error.html</form-error-page>
    </form-login-config>
</login-config>

下面是实现 REST 接口(interface)和 java beans 的代码示例,我删除了样板代码并混淆了与“用例”相关的名称。 一个 Jax-RS bean 的示例:

@Stateless
@Path("api/my")
public class myFacadeREST {
    @EJB
    myFacade myFacade;

    @Context  //injected response proxy supporting multiple threads
    private HttpServletResponse response;

    @POST
    @Consumes({MediaType.APPLICATION_JSON})
    public void create(DataStuff entity) {
        myFacade.create(entity);
    }

    @GET
    @Path("{id}")
    @Produces({MediaType.APPLICATION_JSON})
    public DataStuff find(@PathParam("id") String id) {
        return myFacade.find(id);
    }
}

以及注入(inject)的 EJB 的片段,我需要在其中以编程方式访问安全上下文和主体信息:

@DeclareRoles({"administrator","operator","user"})
@PermitAll
@Stateless
public class myFacade {

    @PersistenceContext(unitName = "myPersistencePU")
    private EntityManager em;

    @Context SecurityContext securityContext;
    @Resource SecurityContext sc; //I have tried both :-(

    public DataStuff find(Object id) {
        //Here I get a NullPointerException, tried both sc and securitycontext
        String username = securityContext.getUserPrincipal().getName();
        if(username.equals("gino"){
            return null;
        }
        return getEntityManager().find(entityClass, id);
    }
}

我尝试过使用和不使用@DeclareRoles、@PermitAll,但 securityContext 和 sc 变量始终为 null。也许我错过了一些东西,但我知道安全信息通过 bean 调用神奇地移动。

问题

  • 如何将安全上下文从 Jax-RS 类传播到 ejb bean?
  • 安全信息是否按照我的预期自动管理?或者..
  • 我需要改进或添加其他 jboss-?.xml 配置文件吗? 或者..
  • 我是否需要更改调用 Jax-RS beans 中的某些内容以便 将安全信息传播到被调用的 bean?或者..
  • 或者我做错了什么?

提前谢谢您 问候

最佳答案

我已经找到答案了,问题已经被问过here

SecurityContext 仅适用于 JAX-RS bean,您需要将 EJBContext 对象代替 SecurityContext 注入(inject)到其他 java bean 中。 您还可以使用 SessionContext 对象,但 EJBContext 接口(interface)类似于 SecurityContext 接口(interface)。这是工作版本:

@DeclareRoles({"administrator","operator","user"})
@PermitAll
@Stateless
public class myFacade {

    @PersistenceContext(unitName = "myPersistencePU")
    private EntityManager em;

    @Resource EJBContext securityContext;

    public DataStuff find(Object id) {
        //Now the securityContext is != null :-D
        String username = securityContext.getCallerPrincipal().getName();
        if(username.equals("gino"){
            return null;
        }
        return getEntityManager().find(entityClass, id);
    }
}

关于java - JAX-RS + EJB,ejb 内的 SecurityContext 为 null,在 WildFly 10.1 上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42111837/

相关文章:

java - Inno Setup - 如何自动允许 Java 通过防火墙

java - 关于 Java 中的 RandomAccessFile 的问题?

java - 什么是 Java 中的面向组件编程?

java - JBoss AS 7 Bean 查找 EJB

java - 实体的JPA集合字段是可修改的

Java JSP - 删除 .DS_Store 并显示正确的文件夹名称

java - 如何打印报告

java - 确保恶意 apk 没有与我的服务器通信

scala - 如何使用scala和play实现安全授权?

security - 开发人员应该有权访问什么?