Как использовать/настроить JAX-RS 2.0, SpringSecurity 3.1.+, EJB 3.2 вместе

В настоящее время я пытаюсь настроить проект с этими основными технологиями:

  • JavaEE 7
  • EJB 3.2
  • JAX-RS (Джерси) 2.0
  • Стеклянная рыбка 4
  • Весенняя безопасность 3.1.5

Я видел, что можно написать что-то подобное

@Stateless
@Path("apath")
public class WebResource {
    @EJB
    private SomeService serviceInjected;

    @GET
    public Response doSomething() {
        return Response.ok(injectedService.doSomethingElse()).build();
    }
}

Затем это означает, что компонент сеанса SomeService внедряется контейнером, и как только мы вызываем путь: ///apath, все работает нормально.

Теперь я пытаюсь интегрировать инфраструктуру SpringSecurity в этот код. Итак, мой код стал таким:

@Component
@Stateless
@Path("apath")
public class WebResource {
    @EJB
    private SomeService serviceInjected;

    @GET
    @PreAuthorized("hasPermission('ROLE_SOMETHING')")
    public Response doSomething() {
        return Response.ok(injectedService.doSomethingElse()).build();
    }
}

Но это не работает. Все, кроме аннотаций SpringSecurity, продолжает работать. Аннотации авторизации просто не учитываются.

В файле конфигурации SpringSecurity у меня есть что-то вроде этого:

<security:global-method-security
    access-decision-manager-ref="preVoteAccessDecisionManager"
    pre-post-annotations="enabled" />

со всем, что связано с цепочкой фильтров и так правильно настроено. Например, у меня так:

<beans:bean id="securityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
    <beans:property name="securityMetadataSource">
        <security:filter-security-metadata-source>
            <security:intercept-url pattern="/**" access="ROLE_TEST" />
        </security:filter-security-metadata-source>
    </beans:property>
    <beans:property name="authenticationManager" ref="authenticationManager" />
    <beans:property name="accessDecisionManager" ref="accessDecisionManager" />
</beans:bean>

И я вижу в журналах своего сервера Glassfish 4, что SpringSecurity управлял доступом ROLE_TEST для моего аутентифицированного пользователя. Я также вижу, что мой аутентифицированный пользователь имеет список ролей, которые я ожидаю.

Я также пытался использовать эту конфигурацию и полагаться на аннотации javax.annotation.security, как показано ниже:

<security:global-method-security
    access-decision-manager-ref="preVoteAccessDecisionManager"
    jsr250-annotations="enabled" />

@Stateless
@Path("apath")
public class WebResource {
    @EJB
    private SomeService serviceInjected;

    @GET
    @RolesAllowed("ROLE_SOMETHING")
    public Response doSomething() {
        return Response.ok(injectedService.doSomethingElse()).build();
    }
}

На этот раз аннотация работает, и при аутентификации пользователя возникает исключение. Но в этом случае у моего пользователя есть роли, но SecurityContext, используемый контейнером, не заполнен информацией о принципале и ролях, относящейся к пользователю, аутентифицированному SpringSecurity.

Наконец, мой вопрос (ы). Есть ли способ интегрировать авторизацию JAX-RS / @Stateless / SpringSecurity вместе? Если нет, есть ли способ заполнить SecurityContext из SrpingSecurity, чтобы javax.annotation.security работал как шарм?

Заранее спасибо за любую помощь, советы, хитрости или что-то еще, что может решить мои проблемы: D


person Laurent    schedule 12.11.2013    source источник


Ответы (1)


Аннотации безопасности методов Spring Security обычно работают только с bean-компонентами Spring, чей жизненный цикл контролируется Spring. Это не включает EJB. Однако, если вы хотите, вы можете использовать интеграцию AspectJ, которая будет работать для любого объекта, включая экземпляры EJB. В кодовой базе Spring Security есть пример. который вы можете использовать в качестве ссылки. Возможно, также стоит подумать о том, нужно ли вам вообще использовать EJB.

person Shaun the Sheep    schedule 12.11.2013