創建自定義登錄表單
本指南建立在Hello Spring MVC安全Java配置之上,以解釋如何使用Spring Security Java Configuration配置和使用自定義登錄表單。
設置樣本
本節概述如何在Spring Tool Suite(STS)中設置工作區,以便您可以按照本指南進行操作。下一節概述了如何將Spring Security應用到現有應用程序的一般步驟。雖然您可以簡單地將這些步驟應用於現有的應用程序,但我們鼓勵您遵循本指南以降低復雜性。
獲取示例項目
將Spring Security發行版解壓縮到已知位置,並將其記錄為SPRING_SECURITY_HOME。
導入hellomvc示例應用程序
為了遵循,我們鼓勵您將hellomvc示例應用程序導入到您的IDE中。您可以使用任何您喜歡的IDE,但本指南中的說明將假設您使用的是Spring Tool Suite(STS)。
已完成的示例應用程序可以在SPRING_SECURITY_HOME / samples / javaconfig / form中找到 |
-
如果您沒有安裝STS,請從https://spring.io/tools下載STS
-
啟動STS並使用以下步驟將示例應用程序導入到STS中:
-
文件→導入
-
現有的Maven項目
-
點擊下一步>
-
點擊瀏覽...
-
導航到樣本(即SPRING_SECURITY_HOME / samples / javaconfig / hellomvc)並單擊確定
-
點擊完成
-
運行hellomvc應用程序
在下面的練習中,我們將修改spring-security-samples-javaconfig-hellomvc應用程序。在進行任何更改之前,最好驗證樣本是否正常工作。執行以下步驟以確保spring-security-samples-javaconfig-hellomvc能夠正常工作。
-
右鍵單擊spring-security-samples-javaconfig-hellomvc應用程序
-
選擇運行方式→在服務器上運行
-
選擇最新的tc服務器
-
點擊完成
確認應用程序正在運行:
-
顯示用戶收件箱的頁面可以在使用用戶名用戶和密碼密碼進行驗證之后在http:// localhost:8080 / sample /中看到。
-
嘗試點擊撰寫鏈接並創建一條消息。應顯示消息詳細信息。
-
現在點擊收件箱鏈接並查看列出的消息。您可以點擊摘要鏈接查看再次顯示的詳細信息。
覆蓋默認配置(HttpSecurity)方法
WebSecurityConfigurerAdapter
提供了一些方便的默認設置來快速啟動和運行我們的應用程序。但是,我們的登錄表單看起來不像我們的其他應用程序。我們來看看我們如何更新配置來使用自定義表單。
默認配置(HttpSecurity)
配置(HttpSecurity)方法的默認配置如下所示:
protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin() .and() .httpBasic(); }
該配置可確保:
每個請求都需要用戶進行身份驗證 | |
支持基於表單的身份驗證 | |
支持HTTP基本認證 |
配置自定義登錄頁面
我們希望確保我們能夠彌補在更新中覆蓋這些默認值。打開SecurityConfig
並插入configure方法,如下所示:
// ... import org.springframework.security.config.annotation.web.builders.HttpSecurity; @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login"); } // ... }
該行loginPage("/login")
指示Spring Security
-
當需要認證時,將瀏覽器重定向到/登錄
-
我們負責在/ login請求時呈現登錄頁面
-
當認證嘗試失敗時,將瀏覽器重定向到/ login?錯誤(因為我們沒有另外指定)
-
當/ login?錯誤被請求時,我們負責渲染失敗頁面
-
當我們成功注銷時,將瀏覽器重定向到/ login?注銷(因為我們沒有另外指定)
-
我們負責在/ login?logout請求時呈現注銷確認頁面
繼續並啟動服務器並嘗試訪問http:// localhost:8080 / sample /以查看我們配置的更新。在許多瀏覽器中,您會看到類似於此網頁的重定向循環錯誤。發生什么事?
授予對未經身份驗證的用戶的訪問權限
問題是Spring Security正在保護對我們自定義登錄頁面的訪問。特別是以下情況正在發生:
-
我們向我們的Web應用程序提出請求
-
Spring Security認為我們沒有通過身份驗證
-
我們被重定向到/登錄
-
瀏覽器請求/登錄
-
Spring Security認為我們沒有通過身份驗證
-
我們被重定向到/登錄 ...
為了解決這個問題,我們需要指示Spring Security允許任何人訪問/ login URL。我們可以通過以下更新輕松完成此操作:
// ... @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll(); } // ... }
方法formLogin().permitAll()
聲明指示Spring Security允許任何訪問任何與之關聯的URL(即/ login和/ login?錯誤)formLogin()
。
授予對formLogin() URL的訪問權限並未默認完成,因為Spring Security需要對允許和不允許的內容作出某些假設。為了安全起見,最好確保授予資源訪問權限是明確的。 |
啟動服務器並嘗試訪問http:// localhost:8080 / sample /以查看我們配置的更新。你現在應該得到一個500錯誤,說明錯誤解析模板“登錄”。
創建一個登錄頁面
在Spring Web MVC中,創建我們的登錄頁面有兩個步驟:
-
創建一個控制器
-
創建一個視圖
配置登錄視圖控制器
在Spring Web MVC中,第一步是確保我們有一個可以指向我們視圖的控制器。由於我們的項目將javaconfig / messages項目添加為依賴項,並且它包含用於/ login的視圖控制器,所以我們不需要在我們的應用程序中創建控制器。作為參考,你可以看到下面的配置:
// ... @EnableWebMvc @ComponentScan("org.springframework.security.samples.mvc") public class WebMvcConfiguration implements WebMvcConfigurer { // ... @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/login").setViewName("login"); registry.setOrder(Ordered.HIGHEST_PRECEDENCE); } }
創建一個登錄視圖
我們現有的配置意味着我們所需要做的就是創建一個包含以下內容的login.html文件:
<html xmlns:th="http://www.thymeleaf.org"> <head th:include="layout :: head(title=~{::title},links=~{})"> <title>Please Login</title> </head> <body th:include="layout :: body" th:with="content=~{::content}"> <div th:fragment="content"> <form name="f" th:action="@{/login}" method="post"> <fieldset> <legend>Please Login</legend> <div th:if="${param.error}" class="alert alert-error"> Invalid username and password. </div> <div th:if="${param.logout}" class="alert alert-success"> You have been logged out. </div> <label for="username">Username</label> <input type="text" id="username" name="username"/> <label for="password">Password</label> <input type="password" id="password" name="password"/> <div class="form-actions"> <button type="submit" class="btn">Log in</button> </div> </fieldset> </form> </div> </body> </html>
我們提交我們的用戶名和密碼的URL與我們的登錄表單(即/ login)相同,但使用POST而不是GET。 | |
當驗證失敗時,瀏覽器被重定向到/ login?錯誤,因此我們可以通過檢測參數錯誤是否為非空來顯示錯誤消息。 | |
當我們成功注銷后,瀏覽器被重定向到/ login?logout,因此我們可以通過檢測參數注銷是否為非空來顯示注銷成功消息。 | |
用戶名應該存在於HTTP參數用戶名中 | |
密碼應該存在於HTTP參數密碼中 |
不要顯示關於驗證失敗原因的詳細信息。例如,我們不希望顯示用戶不存在,因為這會告訴攻擊者他們應該嘗試使用不同的用戶名。 |
我們使用Thymeleaf自動將CSRF令牌添加到我們的表單中。如果我們不使用Thymleaf或Spring MVC taglib,我們也可以使用手動添加CSRF令牌<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> 。 |
啟動服務器並嘗試訪問http:// localhost:8080 / sample /以查看我們配置的更新。我們現在看到了我們的登錄頁面,但它看起來並不漂亮。問題是我們沒有授予對css文件的訪問權限。
授予對剩余資源的訪問權
我們需要更新我們的配置,以允許任何人訪問我們的資源和我們的注銷頁面。更新配置,如下所示:
// ... @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/resources/**").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } // ... }
這允許任何人訪問以/ resources /開頭的URL 。由於這是我們的CSS,JavaScript和圖像存儲的地方,我們所有的靜態資源都可以被任何人查看。 | |
正如您所期望的那樣,logout().permitAll() 允許任何用戶請求注銷並查看注銷成功URL。 |
重新啟動服務器並嘗試訪問http:// localhost:8080 / sample /以查看我們配置的更新。我們現在看到一個看起來像我們應用程序其余部分的自定義登錄頁面。
-
嘗試輸入無效的用戶名和密碼。你會看到我們的錯誤消息顯示。
-
嘗試輸入有效的用戶名(用戶名)和密碼(密碼)。您將成功通過身份驗證。
-
嘗試單擊注銷按鈕。您會看到我們的注銷成功消息
結論
您現在應該知道如何使用Spring Security的Java配置添加自定義登錄表單。要了解更多信息,請參閱Spring Security Guides索引頁面。