问题
I'm trying to authenticate users with a JAX-RS filter what seems to work so far. This is the filter where I'm setting a new SecurityContext:
@Provider
public class AuthenticationFilter implements ContainerRequestFilter {
@Override
public void filter(final ContainerRequestContext requestContext) throws IOException {
requestContext.setSecurityContext(new SecurityContext() {
@Override
public Principal getUserPrincipal() {
return new Principal() {
@Override
public String getName() {
return "Joe";
}
};
}
@Override
public boolean isUserInRole(String string) {
return false;
}
@Override
public boolean isSecure() {
return requestContext.getSecurityContext().isSecure();
}
@Override
public String getAuthenticationScheme() {
return requestContext.getSecurityContext().getAuthenticationScheme();
}
});
if (!isAuthenticated(requestContext)) {
requestContext.abortWith(
Response.status(Status.UNAUTHORIZED)
.header(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Example\"")
.entity("Login required.").build());
}
}
private boolean isAuthenticated(final ContainerRequestContext requestContext) {
return requestContext.getHeaderString("authorization") != null; // simplified
}
}
The resource method looks like this:
@GET
// @RolesAllowed("user")
public Viewable get(@Context SecurityContext context) {
System.out.println(context.getUserPrincipal().getName());
System.out.println(context.isUserInRole("user"));
return new Viewable("index");
}
The RolesAllowedDynamicFeature is registered like this:
.register(RolesAllowedDynamicFeature.class)
I can see the expected outputs on the console. But if I uncomment @RolesAllowed("user")
, I get a Forbidden
error and the isUserInRole
method of my SecurityContext is never called. Following the API doc RolesAllowedDynamicFeature should call this method.
How can I use RolesAllowedDynamicFeature?
回答1:
You need to define a priority for your authentication filter, otherwise the RolesAllowedRequestFilter
in RolesAllowedDynamicFeature
will be executed before your AuthenticationFilter
. If you look at the source code, the RolesAllowedRequestFilter
has the annotation @Priority(Priorities.AUTHORIZATION)
, so if you assign @Priority(Priorities.AUTHENTICATION)
to your authentication filter it will be executed before the RolesAllowedRequestFilter
. Like this:
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {
You might also need to actually register the AuthenticationFilter
using register(AuthenticationFilter.class)
, depending on if your server scans for annotations or not.
回答2:
I guess it is because of
@Override
public boolean isUserInRole(String string) {
return false;
}
Which states, that the user has not the required role @RolesAllowed("user") to even enter the execution of the annotated method.
You should implement a more sophisticated isUserInRole Method that checks, wheter a User has a specific Role or not :)
regards
来源:https://stackoverflow.com/questions/17068528/authorization-with-rolesalloweddynamicfeature-and-jersey