我有一个JAX- RS服务,我希望所有用户都可以访问我的服务,但只有那些有权查看结果的用户才能访问我的服务。基于角色的安全性以及现有的REALMS和不良处理方法不符合我的要求。
例如:
问题是:在某些单独的过滤器,安全性上下文或每种REST方法实现中,应在哪里检查用户ID?如何为REST方法提供此ID,按ID过滤请求后,可以在每个方法中注入securityContext吗?
我正在使用GlassFish 4.1和Jersey JAX-RS实现。
您可以在中执行此逻辑ContainerRequestFilter。在这里处理自定义安全功能非常普遍。
ContainerRequestFilter
要考虑的一些事情
该类应带有注释,@Priority(Priorities.AUTHENTICATION)以便在其他过滤器(如果有)之前执行。
@Priority(Priorities.AUTHENTICATION)
您应该SecurityContext在过滤器中使用。我要做的是实现一个SecurityContext。您可以根据需要真正实现它。
SecurityContext
这是一个没有任何安全逻辑的简单示例
@Provider @Priority(Priorities.AUTHENTICATION) public class SecurityFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext requestContext) throws IOException { SecurityContext originalContext = requestContext.getSecurityContext(); Set<String> roles = new HashSet<>(); roles.add("ADMIN"); Authorizer authorizer = new Authorizer(roles, "admin", originalContext.isSecure()); requestContext.setSecurityContext(authorizer); } public static class Authorizer implements SecurityContext { Set<String> roles; String username; boolean isSecure; public Authorizer(Set<String> roles, final String username, boolean isSecure) { this.roles = roles; this.username = username; this.isSecure = isSecure; } @Override public Principal getUserPrincipal() { return new User(username); } @Override public boolean isUserInRole(String role) { return roles.contains(role); } @Override public boolean isSecure() { return isSecure; } @Override public String getAuthenticationScheme() { return "Your Scheme"; } } public static class User implements Principal { String name; public User(String name) { this.name = name; } @Override public String getName() { return name; } } }
注意事项
isUserInRole
User
java.security.Principal
ContainerRequestContext
怎么办?让我们看一个简单的资源类
@Path("secure") public class SecuredResource { @GET @RolesAllowed({"ADMIN"}) public String getUsername(@Context SecurityContext securityContext) { User user = (User)securityContext.getUserPrincipal(); return user.getName(); } }
注意事项:
Principal
@RolesAllowed
SecurityContext.isUserInRole
要在Jersey启用此功能,我们需要注册 RolesAllowedDynamicFeature
RolesAllowedDynamicFeature
@ApplicationPath("/api") public class AppConfig extends ResourceConfig { public AppConfig() { packages("packages.to.scan"); register(RolesAllowedDynamicFeature.class); } }