I am attempting to set up authentication based on roles for a resource I am exposing via Jersey/JAX-RS. This resource exists within a Glassfish instance in which authentication based on roles (specifically, via @RolesAllowed) is currently working as desired. I'm running Jersey within a servlet container:
<servlet-class>
com.sun.jersey.spi.container.servlet.ServletContainer
</servlet-class>
And am enforcing basic auth on my resource; that requirement is being enforced as expected. I have also provided the following initialization parameter to Jersey:
<init-param>
<param-name>com.sun.jersey.spi.container.ResourceFilters</param-name>
<param-value>com.sun.jersey.api.container.filter.RolesAllowedResourceFilterFactory</param-value>
</init-param>
However, when I attempt to actually add an @RolesAllowed annotation, all accesses fail. For example:
@Path("/my/resource")
@ManagedBean
@RolesAllowed({"SYSTEM"})
public class Resource {
// Accesses with credentials for a user that has the SYSTEM role fail!
}
If I inject a security context and call context.isUserInRole(), it returns false for all roles. What's very strange is that if I remove my @RolesAllowed annotation for this resource, and make requests with valid credentials, this class can successfully access EJB's which require that the user be in the same role I was originally trying to test for. It seems approximately like Jersey may be authenticating with the wrong SecurityContext, or some such. Has anyone else experienced this?
I struggled with a similar issue for hours before one line from this IBM article opened my eyes. Surprisingly, not a single book or user guide mentions this critical fact, without which, authentication can't succeed.
When using annotation-based security, web.xml is not optional; quite on the contrary,
<security-constraint>
element must be present; the web container checks for security before JAX-RS does and without a<security-constraint>
, the proper security context is not set. Thus when JAX-RS invokesisUserInRole(role)
, it always returns false.In addition, either
<security-role>
element(s) in web.xml or@DeclareRoles
annotation must be present.Lastly, if using Jersey,
RolesAllowedDynamicFeature
needs to be registered in the Application class to enable annotation-based security.HTH others who struggle with the pathetic documentation, or lack of it, thereof, that's out there.