简体   繁体   中英

Spring Security + JSR 250 + EJB 3.1 not working

My JEE6 webapp (mainly CDI, EJB 3.1 and JSF 2) uses Spring Security 3, but not Spring dependency injection or MVC. I implemented a Spring AuthenticationProvider to handle the login. During login, I add roles to my users depending on some custom business logic.

Now, I want to use JSR 250 annotations to secure my business logic. My business logic is implemented using stateless EJBs (version 3.1).

I include Spring's context XML file in web.xml as follows:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring/applicationContext-security.xml
    </param-value>
</context-param>

And here is the content of the XML file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:security="http://www.springframework.org/schema/security"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/security
      http://www.springframework.org/schema/security/spring-security-3.1.xsd">


<security:global-method-security jsr250-annotations="enabled"/>

<security:http auto-config="false">
    <security:intercept-url pattern="/pages/**" access="ROLE_USER"/>
    <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <security:form-login login-page="/login.jsf"/>
    <security:anonymous/>
    <security:custom-filter ref="logoutFilter" position="LOGOUT_FILTER"/>
</security:http>

<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
    <constructor-arg index="0" value="/login.jsf"/>
    <constructor-arg index="1">
        <list>
            <bean id="customLogoutHandler" class="com.example.client.security.CustomLogoutHandler"/>
            <bean id="securityContextLogoutHandler" class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
        </list>
    </constructor-arg>
    <property name="filterProcessesUrl" value="/logout.jsf"/>
</bean>

<security:authentication-manager>
    <security:authentication-provider ref="customAuthenticationProvider"/>
</security:authentication-manager>

<bean id="customAuthenticationProvider"
      class="com.example.client.security.CustomAuthenticationProvider"/>
</beans>

In my classes, I use class annotations (type level) to say all methods should be only accessible to users with a certain role:

@Model
@RolesAllowed("ROLE_GROUP")
public class UserListAction {

However, also users with only the role ROLE_USER have access to any function of this class. I verified that the users don't have the wrong roles while debugging with the following code:

    Collection<? extends GrantedAuthority> authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();

As expected, the authorities collection doesn't contain the ROLE_GROUP authority.

It seems my annotations are completely ignored, but why? I also tried Spring's pre-post annotations, but they also seem to have no effect.

By default Spring Security uses standard Spring AOP , which is limited to beans which are created by the Spring application context. Objects (such as EJBs) whose lifecycle is not controlled by Spring will not be affected. Likewise if you create an object instance using new or some other framework creates an object on demand.

The only option you have to apply the method security interceptor to all object instances is to use Aspectj. The answers to this question are probably a good place to start.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM