我可以向 JAX-RS 方法添加自定义注释以验证访问权限吗?
例如我有以下方法:
@GET
@Path("/get/current")
public Response getCurrentInfo(@HeaderParam("Authorization") String token){
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS")
.setPrettyPrinting().create();
String email = SecurityProvider.decryptTokenAndGetEmail(token);
if(DB.isAccessPermitted(email)){
Info info = DB.getCurrentInfo();
String json = gson.toJson(info);
return Response.ok(json).build();
}else{
return Response.status(401).build();
}
}
所以改为写在每个方法中:
So instead to write in every method:
if(DB.isAccessPermitted(email)){
Info info = DB.getCurrentInfo();
String json = gson.toJson(info);
return Response.ok(json).build();
}else{
return Response.status(401).build();
}
我将创建例如 @SecurityCheck
注释,注释每个访问受限的方法并仅在一个地方执行检查.是否可以通过注释来实现,是否可以提供 MVCE?谢谢.
I will create for example @SecurityCheck
annotation, annotate every method which has limited access and perform check only in a single place. Is it possible to achieve with annotations and can MVCE be provided?
Thank you.
推荐答案
如果你使用的是JAX-RS 2.0,可以注入ResourceInfo
变成一个ContainerRequestFilter
,然后得到java.lang.reflect.Method
来自.从Method
,你可以得到注解.例如
If you are using JAX-RS 2.0, you can inject ResourceInfo
into a ContainerRequestFilter
, then get the java.lang.reflect.Method
from the. From the Method
, you can get the annotation. For example
@Provider
@Priority(Priorities.AUTHENTICATION)
public class SecurityFilter implements ContainerRequestFilter {
@Context
private ResourceInfo resourceInfo;
// You can get the header from the `requestContext`
@Override
public void filter(ContainerRequestContext requestContext) {
Method resourceMethod = resourceInfo.getResourceMethod();
SecurityCheck annotation = resourceMethod.getAnnotation(SecurityCheck.class);
// get some value from annotation
if (notAllowedAccess) {
throw new WebApplicationException(403);
}
}
}
这个(ResourceInfo
)只有在你需要从注解中获取一些值时才需要,比如@SecurityCheck("SomeRoleAllowed")
.
This (the ResourceInfo
) is only necessary though if you need to get some value from the annotation, like @SecurityCheck("SomeRoleAllowed")
.
如果您不需要该值,并且您想要的只是对任何带注释的方法进行过滤,那么您可以创建一个 DynamicFeature
,在其中将每个方法绑定到一个过滤器.例如
If you don't need the value, and all you want is for any method annotated to be filtered, then you can either create a DynamicFeature
, where you bind each method to a filter. For example
@Provider
public class SecurityCheckDynamicFeature implements DynamicFeature {
@Override
public void configure(ResourceInfo info, FeatureContext context) {
Method method = info.getResourceMethod();
SecurityCheck annotation = method.getAnnotation(SecurityCheck.class);
if (annotation != null) {
context.register(SecurityFilter.class);
}
}
}
或者另一种方法是在自定义注释上使用 @NameBinding
Or another way is to just use @NameBinding
on the custom annotation
@NameBinding
@Target(...)
@Retention
public @interface SecurityCheck {}
然后你需要用注解来注解 SecurityFilter
类.任何带注释的方法或类都将通过过滤器.
Then you need to annotate the SecurityFilter
class with the annotation also. Any method or class annotated will go through the filter.
其他资源:
- 过滤器和拦截器
相关文章