Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@RolesAllowed always rejected (forbidden) on Jersey resource

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?

like image 454
user2825122 Avatar asked Oct 29 '25 05:10

user2825122


1 Answers

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 invokes isUserInRole(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.

like image 123
Abhijit Sarkar Avatar answered Oct 31 '25 01:10

Abhijit Sarkar