@RolesAllowed always rejected (forbidden) on Jerse

2019-05-29 16:12发布

问题:

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?

回答1:

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.