我正在尝试实现我自己的 ContainerRequestFilter 并配置 SecurityContext 。它在 jax-rs 资源上运行良好,但 EJB jax-rs 抛出 javax.ejb.AccessLocalException
我发现的唯一相关的东西是 4 岁,解决方法似乎不太好。
https://java.net/projects/jersey/lists/users/archive/2010-05/message/265

我的自定义 SecurityContext:

@Provider
@PreMatching
public class SecurityFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext filterContext) throws IOException {
        filterContext.setSecurityContext(new Authorizer());
    }

    public class Authorizer implements SecurityContext {

    public Principal getUserPrincipal() {
        return null;
    }

    public boolean isUserInRole(String role) {
        return true;
    }

    public boolean isSecure() {
        return false;
    }

    public String getAuthenticationScheme() {
        return null;
    }
}

经过测试的资源 (无需@Stateless 即可工作)
@Path("test")
@Stateless
public class TestSecureResource {

    @GET
    @RolesAllowed("admin")
    @Path("admin")
    public Response secureTest() {
        return Response.status(200).entity("admin").build();
    }

}

有人知道如何进行这项工作吗?

最佳答案

您可以使用 JAX-RS SecurityContext 作为 API 而不是 SPI。应用程序开发人员很少提供 SecurityContext 实现。如果您这样做,您必须知道它只有“本地 JAX-RS 有效性”,因为它是一个 JAX-RS 特定的 API。 Servlet/Web 容器和 EJB 容器都不能使用它。他们不必这样做,因为 Java SE 和 EE 具有更通用的安全支持。

如果您希望您的安全检查在 Java EE 应用程序中起作用(即 EJB 上的 HttpServletRequest.isUserInRole(...)EJBContext.isCallerInRole(...)javax.annotation.security 注释),您需要使用 Java EE 功能保护您的 Servlet 层。这意味着在 <security-constraint> 中使用例如 web.xml 。您可以使用 * 作为 <role-name> 意味着“所有经过身份验证”的用户都可以调用 REST API:

<security-constraint>
    <web-resource-collection>
        <url-pattern>/rest/admin/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>adminRole</role-name>
    </auth-constraint>
</security-constraint>
<security-constraint>
    <web-resource-collection>
        <url-pattern>/rest/orders/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>*</role-name> <!-- all authenticated users -->
    </auth-constraint>
</security-constraint>

当您的 Java EE 应用程序如上所示受到保护时,我们可以使用称为 RolesAllowedDynamicFeature 的 Jersey 特定功能在 JAX-RS 中启用 javax.annotation.security 注释。

注册特征:

@ApplicationPath("/rest")
public class MyApplication extends ResourceConfig {
    public MyApplication() {
        super(AdminResource.class);
        register(RolesAllowedDynamicFeature.class);
    }
}

保护您的资源:

@Path("/admin")
@RolesAllowed("adminRole")
public class AdminResource {
    @GET
    public String get() { return "GET"; }
    ...
}

Jersey User guide for more details about securing JAX-RS applications

所以你很接近。您不需要自己实现 SecurityContext。如果您处理安全的 EJB,则不得实现它。最后,您需要将 JAX-RS 层保护为通用 Web/Servlet 应用程序。我确信您已经保护了您的 Web/HTML 页面。

关于jakarta-ee - EJB jax-rs 资源上的 Jersey 自定义 SecurityContext,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26518941/

10-14 12:21