Announcement Announcement Module
Collapse
No announcement yet.
sec:authorize with role hierarchy not working Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • sec:authorize with role hierarchy not working

    I can't get sec:authorize hasRole() to work with the role hierarchy. If I have a user with role ROLE_BOSS which is the parent of ROLE_WORKER, then <sec:authorize access="hasRole('ROLE_WORKER')"> is false for some reason. In my service classes @PreAuthorize("hasRole('ROLE_WORKER')") does work however. I assumed they both used the same evaluator, so why doesn't the taglib work? Thanks for the help.

    JSP:
    Code:
          <sec:authorize access="hasRole('ROLE_BOSS')">
            <p>This shows up.</p>
          </sec:authorize>
          <sec:authorize access="hasRole('ROLE_WORKER')">
            <p>This does not show up, but should.</p>
          </sec:authorize>
    -config.xml security:
    Code:
      <bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
        <property name="permissionEvaluator" ref="permissionEvaluator"/>
        <property name="roleHierarchy" ref="roleHierarchy"/>
      </bean>
    
      <sec:global-method-security pre-post-annotations="enabled">
        <sec:expression-handler ref="expressionHandler"/>
      </sec:global-method-security>
    
      <bean id="permissionEvaluator" class="com.myapp.security.MyPermissionEvaluator">
        <constructor-arg index="0">
          <map key-type="java.lang.String" value-type="com.myapp.security.Permission">
            <entry key="contractReadAccess" value-ref="contractReadPermission"/>
            <entry key="contractWriteAccess" value-ref="contractWritePermission"/>
          </map>
        </constructor-arg>
      </bean>
    
      <bean id="contractReadPermission" class="com.myapp.security.ContractReadPermission"/>
      <bean id="contractWritePermission" class="com.myapp.security.ContractWritePermission"/>
    
      <sec:http use-expressions="true" access-decision-manager-ref="accessDecisionManager">
        <sec:intercept-url pattern="/worker/**" access="isAuthenticated()" requires-channel="https"/>
        <sec:intercept-url pattern="/boss/**" access="hasRole('ROLE_BOSS')" requires-channel="https"/>
    
        <sec:form-login login-page="/login" authentication-failure-url="/login?login_error=1" authentication-success-handler-ref="successHandler"/>
        <sec:logout logout-url="/logout" logout-success-url="/login" invalidate-session="true"/>
        <sec:remember-me/>
      </sec:http>
    
      <bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
        <constructor-arg>
          <list>
            <ref bean="roleVoter" />
            <bean 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 class="org.springframework.security.access.vote.AuthenticatedVoter"/>
          </list>
        </constructor-arg>
      </bean>
    
      <bean id="roleVoter" 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_BOSS > ROLE_WORKER
          </value>
        </property>
      </bean>
    
      <sec:authentication-manager alias="authenticationManager">
        <sec:authentication-provider user-service-ref="myUserDetailsService"/>
      </sec:authentication-manager>

  • #2
    Very strange and I don't think this is correct, but it seems to work. I started digging through the Spring source code and I think I got it to work by taking the DefaultWebSecurityExpressionHandler out of the accessDecisionManager and placing it at the very top of all my security configurations. So at the top of my -config.xml I have this:

    Code:
      <bean id="webExpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
        <property name="permissionEvaluator" ref="permissionEvaluator"/>
        <property name="roleHierarchy" ref="roleHierarchy"/>
      </bean>
    And my accessDecisionManager is now:

    Code:
      <bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
        <constructor-arg>
          <list>
            <ref bean="roleVoter" />
            <bean class="org.springframework.security.web.access.expression.WebExpressionVoter">
              <property name="expressionHandler" ref="webExpressionHandler"/>
            </bean>
            <bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
          </list>
        </constructor-arg>
      </bean>

    Comment


    • #3
      I have a working webExpressionHandler and methodExpressionHandler, but for the life of me I can't get (HttpServletRequest)request.isUserInRole("ROLE_WOR KER") to return true when I am just a ROLE_BOSS, which should be the parent of ROLE_WORKER. Why is this?

      Comment


      • #4
        Have you had any luck in resolving this?

        I have come across the exact same problem yesterday and I am tearing my hair out.

        The Role RoleHierarchyVoter works as expected within the intercept urls but when I try and use it through the authorize taglibs the WebExpressionVoter blatantly ignores the roles and simply denies access.

        Comment

        Working...
        X