SecurityContext doesn't work with @RolesAllowed
Solution 1
Make sure you have your AuthorizationFilter
either registered in your MyApplication
(see Registering Resources and Providers in Jersey 2) or annotated with @Provider (to make it discoverable by package scanning).
In order to use security annotations (package javax.annotation.security
) to restrict access to your resources you need to register RolesAllowedDynamicFeature.
EDIT 1
Your AuthorizationFilter
has to be also annotated with @PreMatching
which means that the filter is invoked before matching phase (uri -> resource). Otherwise filters registered by RolesAllowedDynamicFeature
(invoked during this phase) won't see the custom SecurityContext
.
EDIT 2
Jersey User Guide - Authorization - securing resources
Solution 2
In a real application, defining your own ResourceConfig
means you have to edit it every time you add a new resource (class).
A nice way to avoid that problem is to register the RolesAllowedDynamicFeature
class in an <init-param>
to the <servlet>
in your web.xml
like this:
<servlet>
<servlet-name>your_servelet_name</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature</param-value>
</init-param>
If you do that then you can put this in to dynamically register all resources in particular packages:
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.your-domain.your-packages-1,com.your-domain.your-packages-2</param-value>
</init-param>
Comments
-
tobypls almost 2 years
I'm currently creating a backend server using Jersey 2.5.1 in a Tomcat 7. For the security I'm using the
@RolesAllowed
,@PermitAll
etc. annotations, and I have created my customContainerRequestFilter
andSecurityContext
.My problem is that when my
@RolesAllowed
annotated resource is requested it always denies permission, even if I force myisUserInRole(role)
method to returntrue
. However, myfilter
method gets called. Do you have any suggestions? I'll paste some relevant code below.My
ContainerRequestFilter
implementation:public class AuthorizationFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext request) throws IOException { request.setSecurityContext(new Authorizer()); } }
My
SecurityContext
implementation:public class Authorizer implements SecurityContext { @Override public String getAuthenticationScheme() { return null; } @Override public Principal getUserPrincipal() { return null; } @Override public boolean isSecure() { return false; } @Override public boolean isUserInRole(String role) { return true; } }
My resource:
@Path("/secure") public class TestSecureResource { @GET @PermitAll @Path("/nonsec_test/{text}") public Response nonSecureTest( @PathParam("text") String text){ return Response.status(200).entity(text).build(); } @GET @RolesAllowed("admin") @Path("/sec_test/{text}") public Response secureTest( @PathParam("text") String text){ return Response.status(200).entity(text).build(); } }
My
ResourceConfig
:@ApplicationPath("/") public class MyApplication extends ResourceConfig { public MyApplication() { super(TestSecureResource.class); register(RolesAllowedDynamicFeature.class); register(AuthorizationFilter.class); } }
Relevant parts of my
web.xml
:<servlet-name>Jersey Web Application</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>pkg.backend</param-value> </init-param> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>pkg.backend.MyApplication</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
In this specific case, my access to
secureTest
is always denied. To clarify things; I'm getting HTTP status code 403 - Forbidden.Thank you guys in advance