我们正在将我们的应用程序从Spring 3.0.1升级到Spring 4.1.6。我们还将Spring Security Module升级到4.0.1
我们面临的问题是访问链接。
小背景:
每个链接都标记为某个ROLE,以访问用户需要具有该ROLE的链接
<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>
问题在于,即使角色以&#39; ROLE _&#39;(在阅读不同的博客和问题后发现这一点)开始,角色也无法正常工作。所以为了找到问题,我调试了spring安全源,发现RoleVoter的supports()方法返回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,用户也无法访问链接。
答案 0 :(得分:2)
Spring Security 4.x Migration Guide引用sample project on 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的修复确保前缀自动应用于没有该前缀的角色名称。< / p>