Announcement Announcement Module
Collapse
No announcement yet.
Role Hierarchy Not Working Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Role Hierarchy Not Working

    I am attempting to use Spring Security to secure methods using a role hierarchy. Obviously, since I'm posting here, it isn't working.

    First, here's a definition from an interface:
    Code:
    @PreAuthorize("isFullyAuthenticated()")
    List<RetainUser> getByLocation(String location);
    Next, here's the Unit Test I'm trying to use to test it:

    Code:
    @Test
    public void getByLocation_anonymousUser_throwsAccessDeniedException() {
    
        AppUser anonymousUser = (AppUser) retainUserManager.loadUserByUsername("1111");
    
        Authentication auth = provider.authenticate(new PreAuthenticatedAuthenticationToken(anonymousUser, new AppAuthority(anonymousUser, "ROLE_ANONYMOUS")));
        SecurityContext context = new SecurityContextImpl();
        context.setAuthentication(auth);
    
        SecurityContextHolder.setContext(context);
    
        try {
            List<AppUser> testResult = appUserManager.getByLocation("DAYTON");
            fail("call by anonymous user should have thrown AccessDeniedException");
        } catch (AccessDeniedException ex) {
            System.out.println(ex.getMessage());
        }
    }
    Finally, my security.xml file:

    HTML Code:
    <?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.1.xsd
              http://www.springframework.org/schema/security 
              http://www.springframework.org/schema/security/spring-security-3.1.xsd">
    
    <security:global-method-security pre-post-annotations="enabled">
        <security:expression-handler ref="methodSecurityExpressionHandler"/>
    </security:global-method-security>
    
    <bean id="expressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
        <property name="roleHierarchy" ref="roleHierarchy" />
    </bean>
    
    <bean id="methodSecurityExpressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
        <property name="roleHierarchy" ref="roleHierarchy" />
    </bean>
    
    <!-- In order to use a role hierarchy with the Security expressions, the 
        hierarchy needs to be injected into the expression handler -->
    
    
    <!-- Configure static resources to have no Spring Security filters applied 
        to them -->
    <security:http pattern="/common/**" security="none" />
    <security:http pattern="/**/*.png" security="none" />
    <security:http pattern="/styles/**/*.css" security="none" />
    <security:http pattern="/**/*.css" security="none" />
    <security:http pattern="/**/*.js" security="none" />
    <security:http pattern="/login.jsp" security="none" />
    
    <security:http use-expressions="true" access-denied-page="/accountWizard.html"
        access-decision-manager-ref="accessDecisionManager">
    
        <security:anonymous />
        <security:x509 subject-principal-regex="CN=(.*?)," user-service-ref="retainUserManager" />
            <!-- Role Anonymous needs to be able to hit the index controller in order to be -->
            <!-- redirected to the account wizard (if necessary) -->
            <security:intercept-url pattern="/index.html*" access="hasRole('ROLE_ANONYMOUS')" />
            <security:intercept-url pattern="/**/acceptTerms.html*" access="hasRole('ROLE_ANONYMOUS')" />
            <security:intercept-url pattern="/**/accountWizardHome.html*" access="hasRole('ROLE_ANONYMOUS')"/>
            <security:intercept-url pattern="/**/accountPending.html*" access="hasRole('ROLE_ANONYMOUS')"/>
            <!-- Since roles are hierarchal, ROLE_FIELD and above are legal -->
            <security:intercept-url pattern="/**/*.html" access="hasRole('ROLE_FIELD')" />
        <security:session-management>
            <security:concurrency-control
                max-sessions="1" error-if-maximum-exceeded="false" />
        </security:session-management>
    </security:http>
    
    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider
            user-service-ref="appUserManager" />
    </security:authentication-manager>
    
    <bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
        <property name="decisionVoters">
            <list>
                <ref bean="webExpressionVoter" />
                <ref bean="roleHierarchyVoter" />
            </list>
        </property>
    </bean>
    
    <bean id="webExpressionVoter" class="org.springframework.security.web.access.expression.WebExpressionVoter">
        <property name="expressionHandler">
            <bean
                class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
                <property name="roleHierarchy" ref="roleHierarchy" />
            </bean>
        </property>
    </bean>
    
    <bean id="roleHierarchyVoter"
        class="org.springframework.security.access.vote.RoleHierarchyVoter">
        <constructor-arg ref="roleHierarchy" />
    </bean>
    
    <bean id="roleHierarchy"
        class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
        <property name="hierarchy">
            <value>
                ROLE_SYSTEM > ROLE_MANAGER
                ROLE_MANAGER > ROLE_FIELD
                ROLE_FIELD > ROLE_ANONYMOUS
            </value>
        </property>
    </bean>
    
    <bean id="exceptionTranslationFilter"
        class="org.springframework.security.web.access.ExceptionTranslationFilter">
        <property name="authenticationEntryPoint" ref="authenticationEntryPoint" />
        <property name="accessDeniedHandler" ref="accessDeniedHandler" />
    </bean>
    
    <bean id="authenticationEntryPoint"
        class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
        <property name="loginFormUrl" value="/login.jsp" />
        <property name="forceHttps" value="true" />
    </bean>
    
    <bean id="accessDeniedHandler"
        class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
        <property name="errorPage" value="/403.jsp" />
    </bean>
    In the test above, I'm expecting an AccessDeniedException since the expression is "hasRole('ROLE_FIELD')", which outranks ROLE_ANONYMOUS. Unfortunately, the exception isn't thrown.

    Can anyone help?
Working...
X