title: Spring Security Role Hierarchy Not Working
body: <p>I am attempting to use Spring Security to secure methods using a role hierarchy. Obviously, since I'm posting here, it isn't working.</p>
  
  <p>First, here's a definition from an interface:</p>
  
  <pre><code>@PreAuthorize("isFullyAuthenticated()")
  List&lt;RetainUser&gt; getByLocation(String location);
  </code></pre>
  
  <p>Next, here's the Unit Test I'm trying to use to test it:</p>
  
  <pre><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&lt;AppUser&gt; testResult = appUserManager.getByLocation("DAYTON");
          fail("call by anonymous user should have thrown AccessDeniedException");
      } catch (AccessDeniedException ex) {
          System.out.println(ex.getMessage());
      }
  }
  </code></pre>
  
  <p>Finally, my security.xml file:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;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"&gt;
  
  &lt;security:global-method-security pre-post-annotations="enabled"&gt;
      &lt;security:expression-handler ref="methodSecurityExpressionHandler"/&gt;
  &lt;/security:global-method-security&gt;
  
  &lt;bean id="expressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"&gt;
      &lt;property name="roleHierarchy" ref="roleHierarchy" /&gt;
  &lt;/bean&gt;
  
  &lt;bean id="methodSecurityExpressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler"&gt;
      &lt;property name="roleHierarchy" ref="roleHierarchy" /&gt;
  &lt;/bean&gt;
  
  &lt;!-- In order to use a role hierarchy with the Security expressions, the 
      hierarchy needs to be injected into the expression handler --&gt;
  
  
  &lt;!-- Configure static resources to have no Spring Security filters applied 
      to them --&gt;
  &lt;security:http pattern="/common/**" security="none" /&gt;
  &lt;security:http pattern="/**/*.png" security="none" /&gt;
  &lt;security:http pattern="/styles/**/*.css" security="none" /&gt;
  &lt;security:http pattern="/**/*.css" security="none" /&gt;
  &lt;security:http pattern="/**/*.js" security="none" /&gt;
  &lt;security:http pattern="/login.jsp" security="none" /&gt;
  
  &lt;security:http use-expressions="true" access-denied-page="/accountWizard.html"
      access-decision-manager-ref="accessDecisionManager"&gt;
  
      &lt;security:anonymous /&gt;
      &lt;security:x509 subject-principal-regex="CN=(.*?)," user-service-ref="retainUserManager" /&gt;
          &lt;!-- Role Anonymous needs to be able to hit the index controller in order to be --&gt;
          &lt;!-- redirected to the account wizard (if necessary) --&gt;
          &lt;security:intercept-url pattern="/index.html*" access="hasRole('ROLE_ANONYMOUS')" /&gt;
          &lt;security:intercept-url pattern="/**/acceptTerms.html*" access="hasRole('ROLE_ANONYMOUS')" /&gt;
          &lt;security:intercept-url pattern="/**/accountWizardHome.html*" access="hasRole('ROLE_ANONYMOUS')"/&gt;
          &lt;security:intercept-url pattern="/**/accountPending.html*" access="hasRole('ROLE_ANONYMOUS')"/&gt;
          &lt;!-- Since roles are hierarchal, ROLE_FIELD and above are legal --&gt;
          &lt;security:intercept-url pattern="/**/*.html" access="hasRole('ROLE_FIELD')" /&gt;
      &lt;security:session-management&gt;
          &lt;security:concurrency-control
              max-sessions="1" error-if-maximum-exceeded="false" /&gt;
      &lt;/security:session-management&gt;
  &lt;/security:http&gt;
  
  &lt;security:authentication-manager alias="authenticationManager"&gt;
      &lt;security:authentication-provider
          user-service-ref="appUserManager" /&gt;
  &lt;/security:authentication-manager&gt;
  
  &lt;bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased"&gt;
      &lt;property name="decisionVoters"&gt;
          &lt;list&gt;
              &lt;ref bean="webExpressionVoter" /&gt;
              &lt;ref bean="roleHierarchyVoter" /&gt;
          &lt;/list&gt;
      &lt;/property&gt;
  &lt;/bean&gt;
  
  &lt;bean id="webExpressionVoter" class="org.springframework.security.web.access.expression.WebExpressionVoter"&gt;
      &lt;property name="expressionHandler"&gt;
          &lt;bean
              class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"&gt;
              &lt;property name="roleHierarchy" ref="roleHierarchy" /&gt;
          &lt;/bean&gt;
      &lt;/property&gt;
  &lt;/bean&gt;
  
  &lt;bean id="roleHierarchyVoter"
      class="org.springframework.security.access.vote.RoleHierarchyVoter"&gt;
      &lt;constructor-arg ref="roleHierarchy" /&gt;
  &lt;/bean&gt;
  
  &lt;bean id="roleHierarchy"
      class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl"&gt;
      &lt;property name="hierarchy"&gt;
          &lt;value&gt;
              ROLE_SYSTEM &gt; ROLE_MANAGER
              ROLE_MANAGER &gt; ROLE_FIELD
              ROLE_FIELD &gt; ROLE_ANONYMOUS
          &lt;/value&gt;
      &lt;/property&gt;
  &lt;/bean&gt;
  
  &lt;bean id="exceptionTranslationFilter"
      class="org.springframework.security.web.access.ExceptionTranslationFilter"&gt;
      &lt;property name="authenticationEntryPoint" ref="authenticationEntryPoint" /&gt;
      &lt;property name="accessDeniedHandler" ref="accessDeniedHandler" /&gt;
  &lt;/bean&gt;
  
  &lt;bean id="authenticationEntryPoint"
      class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"&gt;
      &lt;property name="loginFormUrl" value="/login.jsp" /&gt;
      &lt;property name="forceHttps" value="true" /&gt;
  &lt;/bean&gt;
  
  &lt;bean id="accessDeniedHandler"
      class="org.springframework.security.web.access.AccessDeniedHandlerImpl"&gt;
      &lt;property name="errorPage" value="/403.jsp" /&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p></p>
  
  <p>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.</p>
  
  <p>Can anyone help?</p>