Я следил за учебниками Джерси, чтобы реализовать полностью настраиваемый SecurityContext
для моего приложения. Я создал обычай ContainerRequestFilter
установить SecurityContext
следующим образом:JAX-RS пользовательский SecurityContext приводит к неправильному коду ошибки в Джерси
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
}
}
Логика в методе isUserInRole
не имеет значения, это просто макет, чтобы сделать точку.
Моя конечная точка выглядит что-то вроде:
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();
}
}
Теперь я создал тест (с использованием JerseyTest
), сконфигурированный с пакетами, где два класса:
@Override
protected Application configure() {
return new ResourceConfig().packages("com.my.rest", "com.my.security");
}
Если я выполняю следующее в моем испытания:
Response response = target("people/[email protected]")
.request().header("token", "token-for-admin").delete();
Assert.assertEquals(200, response.getStatus());
все работает нормально.
Однако, если выполнить следующее:
Response response = target("people/[email protected]").request().delete();
Assert.assertEquals(403, response.getStatus());
Я бы ожидать 403 код ошибки, потому что я не установил маркер аутентификации. Тем не менее, я получаю код ошибки 500 и тестовый ответ Grizzly (контейнер, используемый для теста) с строкой «Запрос не выполнен».
Если я закомментируйте @Provider
аннотацию на SecurityRequestFilter
класса или удалить пакет com.my.security
из тестовой конфигурации, Джерси использует контейнер при условии SecurityContext
и правильно возвращает 403 вместо.
Почему это происходит? Должен ли Джерси возвращать 403 с обычным SecurityContext
тоже? Что мне не хватает?