![](/img/trans.png)
[英]Migrating From Spring Security to Oracle Access Manager
[英]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.