我可以向 JAX-RS 方法添加自定义注释以验证访问吗?
Can I add a custom annotation to JAX-RS method to validate access?
例如我有以下方法:
@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();
}
}
所以改为在每个方法中写入:
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?
谢谢。
如果您使用的是 JAX-RS 2.0,您可以将 ResourceInfo
注入一个 ContainerRequestFilter
,然后从中获取 java.lang.reflect.Method
。从Method
,你可以得到注解。例如
@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")
。
如果您不需要该值,而您只想过滤任何注释的方法,那么您可以创建一个 DynamicFeature
,在其中将每个方法绑定到一个过滤器。例如
@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
@NameBinding
@Target(...)
@Retention
public @interface SecurityCheck {}
然后你还需要用注解来注解SecurityFilter
class。任何方法或 class 注释都将通过过滤器。
其他资源:
例如我有以下方法:
@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();
}
}
所以改为在每个方法中写入:
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?
谢谢。
如果您使用的是 JAX-RS 2.0,您可以将 ResourceInfo
注入一个 ContainerRequestFilter
,然后从中获取 java.lang.reflect.Method
。从Method
,你可以得到注解。例如
@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")
。
如果您不需要该值,而您只想过滤任何注释的方法,那么您可以创建一个 DynamicFeature
,在其中将每个方法绑定到一个过滤器。例如
@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
@NameBinding
@Target(...)
@Retention
public @interface SecurityCheck {}
然后你还需要用注解来注解SecurityFilter
class。任何方法或 class 注释都将通过过滤器。
其他资源: