2014-10-22 2 views
4

Я пытаюсь реализовать свой собственный ContainerRequestFilter и настроить SecurityContext. Он хорошо работает на jax-rs-ресурсах, но EJB jax-rs throws javax.ejb.AccessLocalExceptionДжерси пользовательский SecurityContext на EJB ресурс jax-rs

Только релевантная вещь, которую я нашел, составляет 4 года, и обходной путь не кажется красивым. https://java.net/projects/jersey/lists/users/archive/2010-05/message/265

Мой заказ SecurityContext:

@Provider 
@PreMatching 
public class SecurityFilter implements ContainerRequestFilter { 

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

    public class Authorizer implements SecurityContext { 

    public Principal getUserPrincipal() { 
     return null; 
    } 

    public boolean isUserInRole(String role) { 
     return true; 
    } 

    public boolean isSecure() { 
     return false; 
    } 

    public String getAuthenticationScheme() { 
     return null; 
    } 
} 

Испытано ресурс (работает без @Stateless)

@Path("test") 
@Stateless 
public class TestSecureResource { 

    @GET 
    @RolesAllowed("admin") 
    @Path("admin") 
    public Response secureTest() { 
     return Response.status(200).entity("admin").build(); 
    } 

} 

ли кто-нибудь знает, как сделать эту работу?

ответ

6

Вы можете использовать JAX-RS SecurityContext как API, а не SPI. Для разработчиков приложений нередко предоставляется реализация SecurityContext. Если вам это нужно, вы должны знать, что имеет только «локальную JAX-RS validity», так как это специфический API JAX-RS. Контейнер Сервлета/Веб и контейнер EJB не работают с ним. Им не нужно, поскольку Java SE и EE имеют более общую поддержку безопасности.

Если вы хотите, чтобы ваши проверки безопасности для работы в приложениях Java EE (т.е. HttpServletRequest.isUserInRole(...), EJBContext.isCallerInRole(...) или javax.annotation.security аннотации EJBs), вы должны обеспечить безопасность Servlet слоя с использованием функции Java EE. Это означает использовать, например, <security-constraint> в web.xml. Вы можете использовать * в <role-name> означает «все проверки подлинности» пользователь может вызвать REST API:

<security-constraint> 
    <web-resource-collection> 
     <url-pattern>/rest/admin/*</url-pattern> 
    </web-resource-collection> 
    <auth-constraint> 
     <role-name>adminRole</role-name> 
    </auth-constraint> 
</security-constraint> 
<security-constraint> 
    <web-resource-collection> 
     <url-pattern>/rest/orders/*</url-pattern> 
    </web-resource-collection> 
    <auth-constraint> 
     <role-name>*</role-name> <!-- all authenticated users --> 
    </auth-constraint> 
</security-constraint> 

Когда приложение Java EE обеспечивается, как показано выше, мы можем включить javax.annotation.security аннотаций в JAX-RS с помощью функции Джерси конкретных RolesAllowedDynamicFeature.

Регистрация особенность:

@ApplicationPath("/rest") 
public class MyApplication extends ResourceConfig { 
    public MyApplication() { 
     super(AdminResource.class); 
     register(RolesAllowedDynamicFeature.class); 
    } 
} 

Защитите свои ресурсы:

@Path("/admin") 
@RolesAllowed("adminRole") 
public class AdminResource { 
    @GET 
    public String get() { return "GET"; } 
    ... 
} 

См Jersey User guide for more details about securing JAX-RS applications.

Итак, вы были близки. Вам не нужно самостоятельно вводить SecurityContext. Вы не должны реализовывать его, если имеете дело с защищенными EJB. И, наконец, вам нужно защитить свой уровень JAX-RS как общее приложение Web/Servlet. Я уверен, что вы уже обеспечили свои веб-страницы или HTML-страницы.

1

Я, наконец, решил. Я не мог использовать javax.security.RolesAllowed, так как он обрабатывается иначе, чем контейнер EJB. Поэтому я внедрил свою собственную аннотацию RolesAllowed. Недостаток заключается в том, что он не настолько продвинут, как реализация оригинала javax.security.RolesAllowed. Например, он не поддерживает фильтрацию сущности, как описано в here. Существует спрос со стороны Java EE для интеграции безопасности в следующий выпуск Java EE 8, и я надеюсь, что мы увидим лучшее решение.

Я положил рабочий пример на github.

0

У меня была такая же проблема Ричард, я последовал за руководством по безопасности в Джерси ниже. https://jersey.java.net/documentation/latest/security.html#d0e10816

Я использовал ContainerRequestFilter для аутентификации, здесь я установил пользовательскую реализацию SecurityContext, если была успешно выполнена аутентификация, которая будет использовать рольallalloweddynamic вместе с ролями с учетом аннотаций для авторизации доступа к определенному ресурсу. Эти три компонента позволили мне пройти аутентификацию и авторизацию на уровне приложения, а не на уровне контейнера.

Это отлично работало, пока мое приложение не было преобразовано из сервлета в EJB/сервлет (я добавил аннотацию без сохранения состояния в класс ресурсов jax-rs). EJB использует назначенные роли аннотации для ограничения доступа к своим компонентам на уровне контейнера, поэтому он противоречил моей аутентификации/авторизации на уровне приложения.

Я все еще ищу подходящее решение, даже если оно отключает защиту метода уровня EJB, поэтому я могу оставить его в ContainerRequestFilter для аутентификации и назначить ролиallalloweddynamicfeature. Вот мой пост по этому вопросу.
Client not authorized for this invocation JAX-RS EJB error

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