我在Spring 4.2.0中创建了自定义login form
和create 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>
secuirty配置:
user.setPassword(passwordEncoder.encode(newAccountDetails.getPassword()));
在用户后控制器
自动登录成功创建:
插入数据库之前<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>
密码加密
@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;
}
你使用完全相同的编码器吗?如果你加载配置两次,你最终加载豆2次,你会得到不同的编码器。 –
@ M.Deinum是的我正在使用相同的编码器。在安全配置中,我已经声明了在验证提供程序中用作密码编码器的'BCryptPasswordEncoder'类型的PasswordEncoder。并且在插入数据库之前对用户密码进行编码,使用相同的'PasswordEncoder'。所以我认为情况并非如此。你能解释一下配置加载两次的情况吗?我会检查我的代码。 –
如果你同时在'ContextLoaderListener'和'DispatcherServlet'中加载配置,你会得到2个不同的编码器实例。另一件事是你创建一个身份验证管理器,给它一个ID,但不要将它连接到Spring Security。 –