Question

I followed the Jersey tutorials to implement a completely custom SecurityContext for my application. I created a custom ContainerRequestFilter to set the SecurityContext as follows:

package com.my.security;
@Provider
@Priority(Priorities.AUTHORIZATION)
public class SecurityRequestFilter implements ContainerRequestFilter {
  @Override
  public void filter(ContainerRequestContext requestContext) {
    requestContext.setSecurityContext(new MySecurityContext(requestContext));
  }
  public static final class MySecurityContext implements SecurityContext {
    private String token;
    public MySecurityContext(ContainerRequestContext requestContext) {
      token = requestContext.getHeaderString("token");
    }
    @Override
    public boolean isUserInRole(String role) {
      return role.equals("admin") && token.equals("token-for-admin");
    }
    // other methods omitted
  }
}

The logic in the isUserInRole method is irrelevant, it's just a mock to make the point.

My endpoint looks something like:

package com.my.rest;
@PermitAll
@Path("/people")
public class PeopleRestService {
  @RolesAllowed({"admin"})
  @Path("/{email}")
  @DELETE
  public Response deletePerson(@PathParam("email") final String email) {
    peopleService.removePerson(email);
    return Response.ok().build();
  }
}

Now I created a test (using JerseyTest) configured with the packages where the two classes are:

@Override
protected Application configure() {
  return new ResourceConfig().packages("com.my.rest", "com.my.security");
}

If I execute the following in my test:

Response response = target("people/my@email.com")
  .request().header("token", "token-for-admin").delete();
Assert.assertEquals(200, response.getStatus());

everything works fine.

However, if I execute the following:

Response response = target("people/my@email.com").request().delete();
Assert.assertEquals(403, response.getStatus());

I would expect a 403 error code because I didn't set the authentication token. However, I get a 500 error code and a Grizzly (the container used for the test) HTML response with the string "Request failed.".

If I comment out the @Provider annotation on the SecurityRequestFilter class or remove the package com.my.security from the test configuration, Jersey uses the container provided SecurityContext and correctly returns a 403 instead.

Why is this happening? Shouldn't Jersey return a 403 with a custom SecurityContext too? What am I missing?

Était-ce utile?

La solution

I apologize for my dumbness. the logic in the isUserInRole method is completely relevant! I had a NPE in there that I didn't see and was causing the 500.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top