2014-01-15 3 views
0

У меня есть веб-сервис RESTful, который я хочу разрешить разные роли на разных конечных точках. Например, у меня есть следующий класс с двумя методами, один для доступа к роли администратора, и один для доступа к роли менеджера. Я использую Glassfish и настраиваю JDBCRealm, и я создал двух пользователей, по одному для каждой роли.Mutliple Роли в защищенной REST Конечная точка Внутренняя ошибка сервера

@Stateless 
@Path("testrole") 
@DenyAll 
public class TestRoleREST { 

    @RolesAllowed("admin") 
    @GET 
    @Path("admin") 
    @Produces("application/xml") 
    public TestData getAdmin() { 
     return new TestData("admin", 0); 
    } 

    @RolesAllowed("manager") 
    @GET 
    @Path("manager/{id}") 
    @Produces("application/xml") 
    public TestData getManager(@PathParam("id") Integer id){ 
     return new TestData("manager", id); 
    } 


    @XmlRootElement 
    @XmlAccessorType(XmlAccessType.FIELD) 
    public static class TestData{ 
     private String roleName; 
     private int number; 

     private TestData(){ 
     } 

     public TestData(String roleName, int number){ 
     this.roleName = roleName; 
     this.number = number; 
     } 
    } 
} 

Использование локон на URI: testrole/менеджер/2 возвращается, как ожидается, некоторые XML и то же самое верно на URI: testrole/администратора для пользователя с правами администратора. Если я не предоставляю учетные данные, я получаю HTTP 401 Not Authorized, который ожидается.

curl -X GET -H "Accept:application/xml" -H "Content-Type:application/xml" -u manager:test http://localhost/server/rest/testrole/manager/2 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<testData> 
    <roleName>manager</roleName> 
    <number>2</number> 
</testData> 

Однако, если я использую локон на URI: testrole/администратор с помощью пользователя менеджера, то я получаю HTTP 500 Внутренняя ошибка сервера, которая обусловлена ​​javax.ejb.AccessLocalException: Client not authorized for this invocation.

curl -X GET -H "Accept:application/xml" -H "Content-Type:application/xml" -u manager:test http://localhost/server/rest/testrole/admin 

Почему не идентифицированный пользователь просто получить HTTP 401, 403 или какой-либо другой нормальный код ошибки? Есть ли способ настроить приложение для возврата предпочтительного кода ошибки HTTP или я пропустил какой-то бит конфигурации?

Кажется немного тяжело сдавать AccessLocalException, которое наследует от RuntimeException только потому, что аутентифицированный пользователь попытался получить доступ к неавторизованному URI.

Этот вопрос (JPA Glassfish Database Update Issue), похоже, имеет дело с теми же исключениями и соображениями, но я не понимаю, как и даже если он относится к моему вопросу. У меня есть работающий сервис при использовании правильно аутентифицированного и авторизованного пользователя.

ответ

0

Я нашел частичное решение моего вопроса в ответе на другой несколько несвязанный вопрос (JAX-RS — How to return JSON and HTTP status code together?). Ответ состоял в том, чтобы использовать javax.ws.rs.ext.ExceptionMapper для маскировки исключения внутреннего сервера на стороне клиента. Это все еще вызывает создание трассировки стека на сервере, но, по крайней мере, клиент не подвергается действию HTTP-кода.

Код для картографа достаточно прост и позволяет мне настроить ответ при работе с AccessLocalException.

@Provider 
public class ApplicationExceptionMapper implements ExceptionMapper<AccessLocalException> { 

    @Override 
    public Response toResponse(AccessLocalException exception) { 
     return Response.status(Response.Status.NOT_FOUND).build(); 
    } 
} 

Как я уже сказал в начале, это частичный ответ, потому что я до сих пор считаю, что сервер не должен генерировать исключение для прошедшего проверку подлинности пользователя, обращающегося несанкционированную конечную точку, но, возможно, это то, что предназначено оригинальные разработчики. Если в головоломке есть еще одна часть с точки зрения настройки ролей на конечных точках REST, чтобы не генерировать AccessLocalException, поделитесь ею. В то же время я могу жить с этим решением ExceptionMapper.

Смежные вопросы