1. 程式人生 > >spring security登入

spring security登入

form-login是spring security名稱空間配置登入相關資訊的標籤,它包含如下屬性: 
1. login-page 自定義登入頁url,預設為/login 
2. login-processing-url 登入請求攔截的url,也就是form表單提交時指定的action 
3. default-target-url 預設登入成功後跳轉的url 
4. always-use-default-target 是否總是使用預設的登入成功後跳轉url 
5. authentication-failure-url 登入失敗後跳轉的url 
6. username-parameter 使用者名稱的請求欄位 預設為userName 
7. password-parameter 密碼的請求欄位 預設為password 
8. authentication-success-handler-ref 指向一個AuthenticationSuccessHandler用於處理認證成功的請求,不能和default-target-url還有always-use-default-target同時使用 
9. authentication-success-forward-url 用於authentication-failure-handler-ref 
10. authentication-failure-handler-ref 指向一個AuthenticationFailureHandler用於處理失敗的認證請求 
11. authentication-failure-forward-url 用於authentication-failure-handler-ref 
12. authentication-details-source-ref 指向一個AuthenticationDetailsSource,在認證過濾器中使用

spring security登入相關的過濾器

首先應注意的一點是,spring security 3.x 預設的登入攔截URL是/j_spring_security_check,而spring security 4.x預設攔截的URL是/login。在spring security中,具體處理表單登入驗證的是o.s.s.w.a.UsernamePasswordAuthenticationFilter,另外一個過濾器o.s.s.w.a.ui.DefaultLoginPageGeneratingFilter用於在沒有指定登入頁時動態生成一個預設登入頁

登入配置

登入頁面 login.jsp

 
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"

  2. pageEncoding="UTF-8"%>

  3. <!DOCTYPE html>

  4. <html>

  5. <head>

  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

  7. <title>Insert title here</title>

  8. </head>

  9. <body onload='document.f.username.focus();'>

  10. <h3>Login with Username and Password</h3>

  11. <form name='f' action='${pageContext.request.contextPath }/login'

  12. method='POST'>

  13. <table>

  14. <tr>

  15. <td>User:</td>

  16. <td><input type='text' name='username' value=''></td>

  17. </tr>

  18. <tr>

  19. <td>Password:</td>

  20. <td><input type='password' name='password' /></td>

  21. </tr>

  22. <tr>

  23. <td colspan='2'><input name="submit" type="submit"

  24. value="Login" /></td>

  25. </tr>

  26. </table>

  27. </form>

  28. </body>

  29. </html>

登入成功頁面 index.jsp

 
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

  2. <!DOCTYPE html>

  3. <html>

  4. <head>

  5. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

  6. <title>Insert title here</title>

  7. </head>

  8. <body>

  9. 登入成功

  10. </body>

  11. </html>

登入失敗頁面 login-failure.jsp

 
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

  2. <!DOCTYPE html>

  3. <html>

  4. <head>

  5. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

  6. <title>Insert title here</title>

  7. </head>

  8. <body>

  9. 登入失敗

  10. </body>

  11. </html>

頁面配置完成,剩下的就是對映url到具體的頁面

登入成功頁面對映 HelloController.java

 
  1. @Controller

  2. public class HelloController {

  3.  
  4. @RequestMapping(value={"/welcome","/"},method=RequestMethod.GET)

  5. public String welcome(){

  6. return "index";

  7. }

  8. }

登入頁面及登入失敗頁面對映 LoginController.java

 
  1. @Controller

  2. public class LoginController {

  3.  
  4. @RequestMapping(value = "/login", method = RequestMethod.GET)

  5. public String loginPage(@RequestParam(value = "error", required = false) String error, Model model) {

  6. if (error != null) {

  7. return "login-failure";

  8. }

  9. return "login";

  10. }

  11. }

spring security配置 spring-security.xml

 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <bean:beans xmlns="http://www.springframework.org/schema/security"

  3. xmlns:bean="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

  5. http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">

  6.  
  7. <http pattern="/login" security="none"></http>

  8.  
  9. <http auto-config="true" use-expressions="true">

  10. <intercept-url pattern="/*" access="hasRole('ROLE_USER')" />

  11. <form-login login-page="/login" login-processing-url="/login" always-use-default-target="true"

  12. default-target-url="/welcome" authentication-failure-url="/login?error=error" />

  13. </http>

  14. <authentication-manager alias="authenticationManager">

  15. <authentication-provider>

  16. <user-service>

  17. <user authorities="ROLE_USER" name="guest" password="guest" />

  18. </user-service>

  19. </authentication-provider>

  20. </authentication-manager>

  21.  
  22. </bean:beans>

現在,配置基本完成,啟動專案後,在登入頁面輸入使用者名稱和密碼,不管正確與否都會有405錯誤Request method ‘POST’ not supported。為什麼會出現這個錯誤呢?

登入請求405錯誤

在登入請求中出現405錯誤,其實是我們在配置過程中,spring mvc和spring security出現了一點衝突導致的。

首先,請注意下面這兩個配置段

<http pattern="/login" security="none"></http>
  • 1
<form-login login-page="/login" login-processing-url="/login" ......
  • 1

第一個配置告訴spring security,類似於/login的url請求不做過濾處理,而第二個配置資訊又告訴spring security url為/login的post請求登入請求處理。正是這種衝突導致了405錯誤的發生。

既然知道了錯誤原因,那麼只要避免衝突就能解決這個問題:使登入頁的請求和登入處理的請求不一致,然後只配置登入頁的請求不做攔截處理.

我採用的方法是使用預設的登入URL /login,修改登入頁面跳轉url為/loginPage。請自行修改程式碼和配置資訊

這樣是不是就大工告成了呢?很遺憾,當你啟動程式時,輸出使用者名稱和密碼,不管正確與否,都會有404 Not Found等著你,這又是為什麼呢?

登入請求404錯誤

首先,建議你看一下spring security自動生成的登入頁原始碼,你會發現有如下程式碼

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
  •  

對於什麼是csrf,請自行參考網上的資料。

spring security預設情況下csrf protection是開啟的,由於我們的登入頁沒有配置csrf的相關資訊,因此spring security內建的過濾器將此連結置為無效連結

解決辦法就是配置csrf protection為不可用狀態,在配置檔案中增加

<csrf disabled="true"/>
  •  

附上完整的spring-security.xml

 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <bean:beans xmlns="http://www.springframework.org/schema/security"

  3. xmlns:bean="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

  5. http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">

  6.  
  7. <http pattern="/loginPage" security="none"></http>

  8.  
  9. <http auto-config="true" use-expressions="true">

  10. <intercept-url pattern="/*" access="hasRole('ROLE_USER')" />

  11. <form-login login-page="/loginPage" login-processing-url="/login" always-use-default-target="true"

  12. default-target-url="/welcome" authentication-failure-url="/loginPage?error=error" />

  13. <csrf disabled="true"/>

  14. </http>

  15. <authentication-manager alias="authenticationManager">

  16. <authentication-provider>

  17. <user-service>

  18. <user authorities="ROLE_USER" name="guest" password="guest" />

  19. </user-service>

  20. </authentication-provider>

  21. </authentication-manager>

  22. </bean:beans>

到此為止,大功告成

原始碼下載

原始碼下載地址https://github.com/SmallBadFish/spring_security_demo/archive/0.1.1-customlogin.zip