Spring Security 4.1升级 - 错误403访问被拒绝

时间:2016-09-02 11:04:43

标签: spring spring-security

升级到Spring Security 4.1.2和Spring 4.3.2时,我得到403 Access Denied Error代码

Spring-Security.xml文件

    ...
<spring:bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter">
</spring:bean>

<spring:bean id="authenticatedVoter" class="org.springframework.security.access.vote.AuthenticatedVoter"/>

<spring:bean id="webExpressionVoter" class="org.springframework.security.web.access.expression.WebExpressionVoter" />

<spring:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
      <spring:constructor-arg>
       <spring:list>
            <spring:ref bean="roleVoter"/>
            <spring:ref bean="authenticatedVoter"/>
            <spring:ref bean="webExpressionVoter"/>
        </spring:list>
  </spring:constructor-arg>
</spring:bean>

<security:http access-decision-manager-ref="accessDecisionManager" auto-config='true' use-expressions="true">

    <security:intercept-url pattern="/login.jsp" access="hasRole('ROLE_ANONYMOUS')" />
    <security:intercept-url pattern="/j_spring_security_check" access="hasRole('ROLE_ANONYMOUS')" />

    <security:intercept-url pattern="/index*" access="hasRole('ROLE_USER')"/>

    <security:form-login login-page="/login.jsp"
        username-parameter="j_username"
        password-parameter="j_password"
        login-processing-url="/j_spring_security_check"
        authentication-failure-url="/accessDenied.jsp" />

    <security:logout invalidate-session="true"  delete-cookies="JSESSIONID"/>

    <security:csrf disabled="true"/>

</security:http>
...

我使用Spring Security AuthenticationProvider类进行身份验证。类中的authenticate(身份验证身份验证)方法已成功执行,并返回新的UsernamePasswordAuthenticationToken(user,pwd,authority)。

错误堆栈跟踪:

2016-09-02 14:59:21,461 DEBUG [http-/127.0.0.1:8080-1] [org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:66)] - Voter: org.springframework.security.access.vote.RoleVoter@52989292, returned: 0
2016-09-02 14:59:21,461 DEBUG [http-/127.0.0.1:8080-1] [org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:66)] - Voter: org.springframework.security.access.vote.AuthenticatedVoter@203cc7cd, returned: 0
2016-09-02 14:59:21,461 DEBUG [http-/127.0.0.1:8080-1] [org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:66)] - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@5e01cc46, returned: -1
2016-09-02 14:59:21,462 DEBUG [http-/127.0.0.1:8080-1] [org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:362)] - Publishing event in Root WebApplicationContext: org.springframework.security.access.event.AuthorizationFailureEvent[source=FilterInvocation: URL: /index.html]
2016-09-02 14:59:21,462 DEBUG [http-/127.0.0.1:8080-1] [org.springframework.security.web.access.ExceptionTranslationFilter.handleSpringSecurityException(ExceptionTranslationFilter.java:186)] - Access is denied (user is not anonymous); delegating to AccessDeniedHandler
org.springframework.security.access.AccessDeniedException: Access is denied
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:124)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)

从错误堆栈跟踪中,WebExpressionVoter返回-1。

2 个答案:

答案 0 :(得分:0)

在spring security文件中用hasAuthority替换hasRole后解析。

答案 1 :(得分:0)

如果我们在很多地方使用 hasAnyRolehasRole ,用 hasAuthority 替换所有的都是不可行的。这是 Spring 中非常令人困惑的升级。如果我们想使用与 Spring 3 相同的角色名称,我们需要附加 ROLE_ 角色名称。例如,如果您使用的是 APP_ADMIN,如果登录用户具有角色 APP_ADMIN,Spring 3 会将 hasRole(APP_ADMIN) 评估为 true。要在 Spring 4 中执行相同的操作,您需要将角色更改为 ROLE_APP_ADMIN 以使 hasRole(APP_ADMIN) 为真。

这完全没有任何意义,除了造成混乱,无论“创造者”给出什么解释