jersey JAX-RS resources can be secured with annotations like this.
@RolesAllowed("user")
@GET
public String get() { return "GET"; }
My requirement is securing dynamically created jersey resources which I have created like this
@ApplicationPath("/")
public class MyApp extends ResourceConfig {
public MyApp() {
packages("com.test.res");
Resource.Builder resourceBuilder = Resource.builder();
resourceBuilder.path("/myresource3");
final ResourceMethod.Builder methodBuilder = resourceBuilder.addMethod("GET");
methodBuilder.produces(MediaType.TEXT_PLAIN).handledBy(new TestInflector());
Resource resource = resourceBuilder.build();
registerResources(resource);
register(RolesAllowedDynamicFeature.class);
}
}
How can I allow only "user" to access this dynamically created resource?
Unfortunately, it appears the
RolesAllowedDynamicFeature
does not support resources created with programmatic API. If you look at the source for RolesAllowedDynamicFeature, you'll see that it looks for the annotations on the resource method and/or resource class to determine whether or not the resource/method should be attached to the filter that handles the authorization.The best way I could think of is to just do the authorization in the
Inflector
. You can see int the source code I linked to, the filter that handles the authorization doesn't really do much. It just checks if theSecurityContext
to see if the roles are allowed. You could use the logic in anInflector
. For exampleIt looks pretty similar to the code in the
RolesAllowedRequstFilter
. We're handling the authorization, then just delegating the return to anotherInflector
. You would just use it likeThe only real noticeable difference in behavior (with using the inflector instead of the filter) is that with the filter, you have the concept of order priority. You can see in the
RolesAllowedRequestFilter
that it uses a priority ofPriorities.AUTHORIZATION
. The reason it uses this is because the authentication filter that happens before this filter should be using the priorityPriorities.AUTHENTICATION
, which makes sure that authentication happens before authorization.In the case of using the inflector, you still have this ordering, i.e. the authentication filter happens before the inflector is applied. How the behavior is different though is say you you want to implement some other filter, You want it to be performed after the authorization so you might have this
Maybe you need to the user to be authorized. The problem when using the inflector is that it doesn't get invoked until after this filter. Which is not what you want because it is dependent on the authorization to have completed.
This is the one con of using the inflector for the authorization.
The other thing I can think of that might work (though I have yet to put all the pieces together, is to use name binding.
You could implement the
AuthorizationFilter
just like theRolesAllowedRequestFilter
. The thing I have yet to figure out is how to get the roles allowed from inside the filter. You obviously can't just pass it to the filter, as it needs to be scoped per resource method. I'm not sure if this can be done or not. It's something I need to play with a bit further.For now, the only thing I can think of that I have tested and works is to just use the inflector.