EJB jax-rs资源上的Jersey自定义SecurityContext

Ric*_*sár 4 jax-rs java-ee glassfish-4 jersey-2.0

我正在尝试实现自己的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

经测试的资源(无@Stateless)

@Path("test")
@Stateless
public class TestSecureResource {

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

}
Run Code Online (Sandbox Code Playgroud)

有人知道如何使这项工作?

小智 6

您可以将JAX-RS SecurityContext用作API而不是SPI.应用程序开发人员提供SecurityContext实现的情况并不常见.如果你这样做,你必须知道它只有"本地JAX-RS有效性",因为它是一个JAX-RS特定的API.Servlet/Web容器和EJB容器都不能使用它.他们没有必要,因为Java SE和EE具有更广泛的安全支持.

如果你希望你的安全检查,以在Java EE应用程序(即作品HttpServletRequest.isUserInRole(...),EJBContext.isCallerInRole(...)javax.annotation.security在注解的EJB),你需要确保你的servlet层使用Java EE功能.这意味着要使用,例如<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>
Run Code Online (Sandbox Code Playgroud)

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

注册功能:

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

保护您的资源:

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

有关保护JAX-RS应用程序的更多详细信息,请参阅Jersey用户指南.

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