Jersey 支持Entity Filtering。除了一般的过滤,它还支持Role-based Entity Filtering using (javax.annotation.security) annotations。
因此您可以在域模型属性上使用@RolesAllowed、@PermitAll 和@DenyAll 注释
public static class Model {
private String secured;
@RolesAllowed({"ADMIN"})
public String getSecured() { return this.secured; }
}
但是,要完成这项工作,您需要在请求过滤器中设置 SecurityContext。 Jersey 将查找 SecurityContext 以验证角色。您可以在this post 中阅读更多相关信息(注意:实体过滤与该帖子中提到的任何真实授权是分开的。但该帖子确实解释了 SecurityContext)。
基本上你会有类似的东西(注意你设置 SecurityContext 的最后一行)。
@PreMatching
public static class SimpleAuthFilter implements ContainerRequestFilter {
private static final Map<String, User> userStore = new ConcurrentHashMap<>();
static {
userStore.put("peeskillet", new User("peeskillet", Arrays.asList("ADMIN", "USER")));
userStore.put("paulski", new User("paulski", Arrays.asList("USER")));
}
@Override
public void filter(ContainerRequestContext request) throws IOException {
final String authHeader = request.getHeaderString("Authorization");
final String username = authHeader.split("=")[1];
final User user = userStore.get(username);
if (user == null) {
throw new NotAuthorizedException("No good.");
}
request.setSecurityContext(new SimpleSecurityContext(user));
}
}
SimpleSecurityContext 只是你自己的一个类,你需要重写isUserInRole 方法并检查用户是否具有角色
private static class SimpleSecurityContext implements SecurityContext {
private final User user;
SimpleSecurityContext(User user) {
this.user = user;
}
@Override
public Principal getUserPrincipal() {
return new Principal() {
@Override
public String getName() {
return user.getUsername();
}
};
}
@Override
public boolean isUserInRole(String role) {
return user.getRoles().contains(role);
}
@Override
public boolean isSecure() {
return false;
}
@Override
public String getAuthenticationScheme() {
return "simple";
}
}
差不多就是这样。您还需要在应用程序中注册 SecurityEntityFilteringFeature 以使其正常运行。
在this Gist查看完整的测试用例