我正在尝试实现我自己的 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/