Java 自定义JAX-RS授权-在每个请求中使用JWT
我有一个JAX-RS服务,我希望我的所有用户都能访问我的服务,但只有那些有权查看结果的用户。基于角色的安全性、现有领域和atuhentication方法不符合我的要求 例如:Java 自定义JAX-RS授权-在每个请求中使用JWT,java,security,rest,glassfish,jax-rs,Java,Security,Rest,Glassfish,Jax Rs,我有一个JAX-RS服务,我希望我的所有用户都能访问我的服务,但只有那些有权查看结果的用户。基于角色的安全性、现有领域和atuhentication方法不符合我的要求 例如: 用户根据一个REST服务进行身份验证,我向他发送带有其ID的JWT令牌 用户请求其他资源,并在每个请求中发送带有其ID的JWT 我检查他的用户id(来自JWT),如果业务逻辑返回结果,我将返回结果,否则我将发送空的结果集或特定的HTTP状态 问题是:在某个单独的过滤器、安全上下文或每个REST方法实现中,我应该在哪里检查用
我使用的是GlassFish 4.1和Jersey JAX-RS实现。您可以在。在这里处理自定义安全特性是很常见的 一些需要考虑的事情
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; }
}
}
需要注意的几件事:
被注入到方法中李>SecurityContext
- 我们获取
并将其转换为主体
。因此,实际上您可以创建实现用户
主体的任何类,并根据需要使用此对象
- 允许使用
注释。对于Jersey,有一个过滤器通过在@roles
注释中传递每个值来检查@RolesAllowed
,以查看是否允许用户访问资源 要在Jersey中启用此功能,我们需要注册SecurityContext.isUserInRole
RolesAllowedDynamicFeature
@ApplicationPath("/api") public class AppConfig extends ResourceConfig { public AppConfig() { packages("packages.to.scan"); register(RolesAllowedDynamicFeature.class); } }
自定义JAX-RS提供程序
resteasy.providers
com.sixturtle.jwt.JWTRequestFilter
resteasy.role.based.security
真的
谢谢您的回复。我想我可以使用ContainerRequestFilter,但我不需要角色和SecurityContext来满足我的需求。仅仅使用servlet过滤器是否太简单了,对于对REST资源的每个请求,我都会对之前发送的JWT头进行解组,从中提取用户信息并将其传递给服务方法,以确定每个方法中用户的授权级别?这似乎是一个简单实用的解决方案,应该可以工作。在servlet过滤器中可以做的事情,在ContainerRequestFilter中也可以做。但对于后者,您可以访问Jersey应用程序库,我通过将JWT数据注入用户主体,然后在我拥有的每个REST方法中从注入的SecurityContext获取数据,实现了您的解决方案。请允许我投票并接受您的帮助,好的,先生。在Wildfly 10中如何做?您如何创建“我的方案”,这是一组角色名称吗?
@ApplicationPath("/api")
public class AppConfig extends ResourceConfig {
public AppConfig() {
packages("packages.to.scan");
register(RolesAllowedDynamicFeature.class);
}
}