Can I add a custom annotation to the JAX-RS method to verify access?

For example, I have the following method:

@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(); } } 

Therefore, instead write in each 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(); } 

I will create, for example, the @SecurityCheck annotation, annotate each method that has limited access and performs validation in only one place. Is it possible to get annotations and is it possible to provide MVCE? Thanks.

+5
source share
1 answer

If you are using JAX-RS 2.0, you can enter ResourceInfo in ContainerRequestFilter , then get java.lang.reflect.Method from. From Method you can get annotation. for instance

 @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); } } } 

This ( ResourceInfo ) is necessary, but if you need to get some value from the annotation, for example @SecurityCheck("SomeRoleAllowed") .

If you don't need a value, and all you want is for any method annotated for filtering, then you can either create a DynamicFeature where you bind each method to a filter. for instance

 @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); } } } 

Or another way is to simply use @NameBinding in a custom annotation

 @NameBinding @Target(...) @Retention public @interface SecurityCheck {} 

Then you also need to annotate the SecurityFilter class with annotation. Any method or class annotated will go through the filter.

Other resources:

+6
source

All Articles