我在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。 –