0

我已经成功地将 spring security 3.0 集成到 web 应用程序中并且运行良好,现在我要将 spring security 3.0 升级到 3.1,并且我的 CustomAuthenticationManager 遇到问题每当我尝试登录时,CustomAuthenticationManager 都会被调用两次。因此,第一次用户身份验证成功并返回 usernamePasswordAuthenticationToken 但该类再次被调用,这次主体返回正确的值但凭据返回 null 因此用户身份验证失败并再次重定向到登录页面,这就是我无法登录的原因。

自定义身份验证管理器:

public class CustomAuthenticationProvider implements AuthenticationProvider {
    @Autowired
    private ILoginService loginService;
    public Authentication authenticate(Authentication authentication)
            throws AuthenticationException {
        UsernamePasswordAuthenticationToken usernamePassswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                authentication.getPrincipal(), authentication.getCredentials());
        if (loginService.authenticateUser((String) authentication.getPrincipal())) {
            if (loginService.validateUserIdAndPass((String) authentication.getPrincipal(), (String) authentication.getCredentials())) {
                usernamePassswordAuthenticationToken.setAuthenticated(false);
            } else
                throw new BadCredentialsException(
                        "Username/Password does not match");
        } else
            throw new BadCredentialsException(
                    "Username/Password does not match");
        return usernamePassswordAuthenticationToken;
    }
    public boolean supports(Class<? extends Object> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}

我的 ApplicationContextSecurity.xml:

<global-method-security pre-post-annotations="enabled">     
    </global-method-security>  
    <beans:bean id="myAccessDecisionManager"
        class="com.app.common.security.repository.MyAccessDecisionManager"> 
    </beans:bean> 

    <http auto-config="true" once-per-request="true"
        access-decision-manager-ref="myAccessDecisionManager" access-denied-page="/jsp/errorPage.jsp">

        <intercept-url pattern="/*.app"  access="ROLE_ANONYMOUS"/>  

         <form-login login-page="/login.app" login-processing-url="/j_spring_security_check"
            default-target-url="/login/validate.app"
            authentication-failure-url="/login.app?login_error=1" />
        <logout logout-url="/j_spring_security_logout"
            logout-success-url="/login.app" invalidate-session="true" /> 
        <session-management invalid-session-url="/login.app"
            session-fixation-protection="newSession">
            <concurrency-control max-sessions="100"
                error-if-maximum-exceeded="false" />
        </session-management>
    </http>

    <authentication-manager>
        <authentication-provider ref="customAuthenticationProvider"></authentication-provider>
    </authentication-manager>

    <beans:bean id="customAuthenticationProvider"
        class="com.app.common.security.repository.CustomAuthenticationProvider">        
    </beans:bean>

请告诉我哪里错了。

4

1 回答 1

0

自 Spring 3.0.3(及更高版本)以来,默认情况下AuthenticationManager会在身份验证尝试( SEC-1493ProviderManager )后清除凭据。您必须是旧版本(Spring Security 的 3.0.3 之前)。

CustomAuthenticationProvider也有缺陷,因为您应该true在成功的身份验证后将身份验证设置为(否则扩展的拦截器AbstractSecurityInterceptor将重新尝试身份验证。

链接

  1. SEC-1493
  2. ProviderManager源码
  3. AbstractSecurityInterceptor javadoc
于 2013-09-24T13:04:03.487 回答