繁体   English   中英

将应用程序从Spring Security 3迁移到4,面临RoleVoter类的问题

[英]Migrating application from spring security 3 to 4, facing issue with RoleVoter class

我们正在将应用程序从Spring 3.0.1升级到Spring 4.1.6。 我们还将Spring Security Module升级到4.0.1

我们面临的问题是访问链接。

小背景:

每个链接都标记有特定的角色,要访问链接,用户需要具有该角色

<security:http  auto-config="false" access-decision-manager-ref="urlAccessDecisionManager" entry-point-ref="authenticationEntryPoint" use-expressions="true">
    <security:access-denied-handler error-page="/admin/error.html" /> 
    <security:csrf disabled="true"/>
    <security:session-management invalid-session-url="/admin/sign-in.html" >
       <!--<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />  -->
    </security:session-management>
    <security:form-login login-page="/admin/sign-in.html" authentication-success-handler-ref="loginSuccessHandler" default-target-url="/admin/index.html"
                         username-parameter="j_username"
                         password-parameter="j_password"
                         login-processing-url="/j_spring_security_check"
                         always-use-default-target="false"
                         authentication-failure-url="/admin/sign-in.html?error=1" />

    <security:logout logout-url="/admin/logout.html" invalidate-session="true" logout-success-url="/admin/sign-in.html"/>   
    <security:intercept-url pattern="/admin/index.html*" access="ROLE_ADMIN_OVERALL_DASHBOARD" />
    <security:intercept-url pattern="/admin/accounts/index.html*" access="ROLE_ADMIN_ACCOUNT_LISTING" />
     ......
     ......
     ......

  </security:http>

为了做出访问决定,我们需要urlAccessDecisionManager以及三个投票器,如下所示:

<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"/>
<bean id="urlAccessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased">
    <constructor-arg>
        <list>
            <ref bean="roleVoter" />
            <bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
            <ref bean="urlCustomVoter"/>
        </list>
    </constructor-arg>
    </bean>

问题是,即使角色以'ROLE_'开头(在阅读了不同的博客和问题后才发现),RoleVoter也无法正常工作。 为了找到问题,我调试了spring安全源,并发现RoleVoter的support()方法返回false。因此我进一步研究了该方法:

public boolean supports(ConfigAttribute attribute) {
        if ((attribute.getAttribute() != null)
                && attribute.getAttribute().startsWith(getRolePrefix())) {
            return true;
        }
        else {
            return false;
        }
    }

事实证明, attribute.getAttribute()返回NULL,因为该属性是WebExpressionConfigAttribute类型的对象,默认情况下,该类型的getAttributed()方法返回NULL。

同时,我调试了使用Spring Security 3.0.1的旧代码,发现在旧代码中,属性对象的类型为SecurityConfig

因此,有人可以指出我们犯了什么配置错误,即使用户已将所有ROLES都标记了他,但由于该错误,用户仍无法访问链接。

Spring Security 4.x迁移指南》引用了Github上的一个示例项目 ,该示例项目显示了对XML配置的更改,以对URL实施特定角色。

根据示例,该行:

<security:intercept-url pattern="/admin/index.html*"
                        access="ROLE_ADMIN_OVERALL_DASHBOARD" />

需要更改为:

<security:intercept-url pattern="/admin/index.html*" 
                        access="hasRole('ROLE_ADMIN_OVERALL_DASHBOARD')" />

(角色名称需要包装在对hasRole()的调用中。

使用Spring Security 4.x,还可以从角色名称中省略ROLE_前缀,因为Spring JIRA 2758的修复程序可以确保将前缀自动应用于没有该前缀的角色名称。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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