为新创建的用户中断添加自动登录登录表单身份验证

时间:2015-10-20 18:59:29

标签: java spring authentication login spring-security

我在Spring 4.2.0中创建了自定义login formcreate new account表单。他们工作得很好。但是现在我已经为新创建的用户实现了自动登录,该用户成功登录了创建的用户。但是,如果我注销并尝试使用相同的凭据再次登录,则身份验证将失败。并且身份验证对其他用户也不起作用。因此,用户能够登录的唯一时间是创建时间。之后认证失败。让我认为自动登录代码由于某种原因破坏了春季登录认证。看看下面的代码。有人猜到为什么会这样吗?

登录表单:

<form:form modelAttribute="loginForm" action="${pageContext.request.contextPath}/login" method="POST">
            Username:<form:input path="username" size="30" />
            Password:<form:password path="password" size="30" />
            <input type="submit" value="Login" />
</form:form>

安全配置:

<security:http auto-config="true" use-expressions="true">
    <security:form-login default-target-url="/home" login-page="/"
        authentication-failure-url="/?error=true" />
    <security:intercept-url pattern="/" access="permitAll" />
    <security:intercept-url pattern="/newaccount"
        access="permitAll" />
        <security:intercept-url pattern="/createAccount/**"
        access="isAnonymous()" />
        <security:intercept-url pattern="/login"
        access="permitAll" />
        <security:intercept-url pattern="/logout"
        access="permitAll" />
    <security:intercept-url pattern="/home"
        access="isAuthenticated()" />
    <security:intercept-url pattern="/**" access="denyAll" />
    <security:csrf disabled="true" />
    <security:logout />
</security:http>

<security:authentication-manager id="authManager">
    <security:authentication-provider>
        <security:jdbc-user-service data-source-ref="dataSource" />
        <security:password-encoder ref="passwordEncoder"></security:password-encoder>
    </security:authentication-provider>
</security:authentication-manager>
<bean id="passwordEncoder"
    class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
</bean>

插入数据库之前的密码加密:

user.setPassword(passwordEncoder.encode(newAccountDetails.getPassword()));

成功创建用户后在控制器中自动登录:

@RequestMapping("/createAccount")
public ModelAndView submitCreateAccount(@ModelAttribute("newAccount") NewAccountDetails newAccountDetails) {
    System.out.println(newAccountDetails);
    ModelAndView mv = new ModelAndView();
    if (userServices.createUserService(newAccountDetails)) {

        System.out.println("user created successfully");
        try {
            userDetails = userDetailService.loadUserByUsername(newAccountDetails.getUsername());
            System.out.println(userDetails);
            UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(userDetails,
                    newAccountDetails.getPassword(), userDetails.getAuthorities());
            authManager.authenticate(authToken);
            if (authToken.isAuthenticated()) {
                System.out.println("New User is authenticated");
                SecurityContextHolder.getContext().setAuthentication(authToken);
                mv.setViewName("redirect:/home");
            } else {
                System.out.println("user not authenticated.");
                mv.setViewName("redirect:/");
            }
        } catch (Exception e) {
            System.err.println("e: " + e);
            mv.setViewName("redirect:/");
        }
    } else {
        System.out.println("user not created");
        mv.setViewName("redirect:/newaccount");
    }
    return mv;
}

1 个答案:

答案 0 :(得分:0)

您使用特定url定义了自己的AuthenticationManager。但是,Spring Security对此特定实例一无所知,仍然使用默认的id。因此,对于注册和登录,您基本上使用authenticationManager的2个不同实例。

要解决此问题,您需要告诉Spring Security要使用哪个,通过将AuthenticationManager属性添加到主authentication-manager-ref元素来执行此操作。

http

或通过自己<security:http auto-config="true" use-expressions="true" authentication-manager-ref="<your-authetnication-manager-id>"> 指定alias

AuthenticationManager

有关详细信息,请参阅http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#ns-auth-manager