Securing with roles annotations not working (Jersey)

自古美人都是妖i 提交于 2019-12-23 01:34:21

问题


I'm new here even though I've found many answers to my problems in here before.

Now I'm looking for help with this: I have this little example resource on my little REST API:

@Path("/greeting")
@PermitAll
public class HelloResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("all")
    public String sayHelloToAll() {
        return "Hello, everybody!";
    }

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @RolesAllowed("admin")
    @Path("admin")
    public String sayHelloToAdmin() {
        return "Hello, admin!";
    }
}

In order to filter roles, I have this implementation of SecurityContext:

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;
    }
}

And this implementation of ContainerRequestFilter:

@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthorizationFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        requestContext.setSecurityContext(new Authorizer());
    }
}

This is my application class:

@ApplicationPath("/")
public class Application extends ResourceConfig {

    public Application() {
        super(HelloResource.class);
        register(AuthorizationFilter.class);
        register(RolesAllowedDynamicFeature.class);        
    }
}

With all this, when I request the URI greeting/all, everything is ok, the string "Hello, everybody!" is shown. But when I request the URI greeting/admin, which should be called when an user in admin role requests it, is never invoked, even when my isUserInRole method always returns true. In fact, my filter method is always called, but my isUserInRole method is never called.

I have followed many advices:

SecurityContext doesn't work with @RolesAllowed

Authorization with RolesAllowedDynamicFeature and Jersey

How to access Jersey resource secured by @RolesAllowed

Best practice for REST token-based authentication with JAX-RS and Jersey

But it doesn't seem to work with anything.

Can anyone please help me? I don't know is there is something I am missing

Thank you all in advance.

EDIT: When I request the URI greeting/admin I get 403 Forbiden by the way (I forgot to say that)


回答1:


Take a look at the source code for the RoleAllowedRequestFilter. When a user is authenticated, it is expected that there be an associated Principal. The filter checks it here

if (rolesAllowed.length > 0 && !isAuthenticated(requestContext)) {
    throw new ForbiddenException(LocalizationMessages.USER_NOT_AUTHORIZED());
}
...
private static boolean isAuthenticated(final ContainerRequestContext requestContext) {
    return requestContext.getSecurityContext().getUserPrincipal() != null;
}

So you need to return a Principal in the getUserPrincipal of the SecurityContext

@Override
public Principal getUserPrincipal() {
    return new Principal() {
        @Override
        public String getName() {
            return "Some Name";
        }
    };
}


来源:https://stackoverflow.com/questions/34497071/securing-with-roles-annotations-not-working-jersey

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!