在前面的篇幅中,咱們對認證和受權流程大體梳理了一遍。在這個過程當中咱們一直都是使用系統生成的默認頁面,登陸成功後也是直接調轉到根路徑頁面。而在實際的開發過程當中,咱們是須要自定義登陸頁面的,有時還會添加各種驗證機制,在登陸成功後會跳轉至指定頁面,還會進行各類美化,甚至是先後端分離的方式。這時,就須要咱們對自定義登陸進行實現。html
本章節使用spring-security-custom-loginjava
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>security-study</artifactId> <groupId>cn.wujiwen.security</groupId> <version>0.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <description>自定義登陸頁面</description> <artifactId>spring-security-custom-login</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> </dependencies> </project>
咱們引入了thymeleaf
,也是官方推薦的作法。web
server: port: 8080 spring: security: user: name: admin password: admin roles: ADMIN
很是的熟悉,端口、基礎用戶等信息spring
@SpringBootApplication public class SecurityLoginApplication { public static void main(String[] args) { SpringApplication.run(SecurityLoginApplication.class,args); } }
自定義SecurityConfig
需繼承WebSecurityConfigurerAdapter
並重寫相關配置便可,因爲今天只涉及到自定義頁面的信息,因此咱們只須要重寫configure(HttpSecurity http)
方法便可。在重寫這個方法前,咱們先來看一下原來這個方法是幹什麼的。apache
protected void configure(HttpSecurity http) throws Exception { http // 1 聲明ExpressionUrlAuthorizationConfigurer,要求全部URL必須登陸認證後才能訪問 .authorizeRequests().anyRequest().authenticated() .and() // 2 聲明一個默認的FormLoginConfigurer .formLogin() .and() // 3 聲明一個默認的HttpBasicConfigurer .httpBasic(); }
Http Basic
認證機制;下面咱們就經過重寫上述的方法來作到自定義登陸頁面等信息後端
@EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); http.authorizeRequests().anyRequest().authenticated() .and().httpBasic().and() // 1 .formLogin().loginPage("/login") // 2 .loginProcessingUrl("/loginAction") // 3 .defaultSuccessUrl("/index") .permitAll(); } }
咱們發現其實和缺省方法中並無太大的差異,只有三處的變化springboot
loginPage()
中將指定自定義登陸頁面的請求路徑loginProcessingUrl()
爲認證的請求接口,也就是咱們常說的form
表單中的action
。若是不指定,將採用loginPage
中的值。defaultSuccessUrl()
爲認證成功後跳轉的頁面地址在springboot中使用html頁面這裏就不過多贅述,通常狀況下在resource下新建templates文件下,將須要的頁面放到該文件下便可。個人路徑爲app
_resource |_templates |_login.html |_index.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> <head> <title>Spring Security Example </title> </head> <body> <div th:if="${param.error}"> 用戶名或密碼錯誤 </div> <div th:if="${param.logout}"> 你已經退出 </div> <form th:action="@{/loginAction}" method="post"> <div><label> 帳號 : <input type="text" name="username"/> </label></div> <div><label> 密碼 : <input type="password" name="password"/> </label></div> <div><input type="submit" value="登陸"/></div> </form> </body> </html>
這裏我將action與loginProcessingUrl()對應,你也能夠本身嘗試更換或使用默認或與loginPage()一致的。前後端分離
到這裏咱們就完成了一個最簡單的表單提交的頁面了。當咱們點擊submit按鈕時,正確的請求路徑將是curl
curl -x POST -d "username=admin&password=admin" http://127.0.0.1:8080/loginAction
這裏可能會有個疑問了,爲啥你的參數就是username和password呢?嗯~ 固然能夠本身指定的啊,由於在FormLoginConfigurer中默認的指定參數
public FormLoginConfigurer() { super(new UsernamePasswordAuthenticationFilter(), null); usernameParameter("username"); passwordParameter("password"); }
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> <head> <title>Spring Security Example</title> </head> <body> <h2>Welcome <b th:text="${username}"></b></h2> </body> </html>
這是個認證成功後的歡迎頁面,比較簡單,顯示當前登陸用戶便可
上面咱們定義了各種路徑和請求地址,接下來咱們須要定義若是將這些頁面映射出來
@Controller public class BaseController { // loginPage("/login") 將跳轉到login.html @GetMapping("/login") public String login() { return "login"; } // index.html @RequestMapping("/index") public String index(Model model, HttpServletRequest request) { model.addAttribute("username",request.getUserPrincipal().getName()); return "index"; } }
到這裏咱們已經完成了一個簡單的自定義登陸頁面的改造了。固然,在實際的項目中須要自定義的東西還有不少不少,好比,當認證不經過時若是操做,當用戶退出登陸時若是操做,這些都沒有去實現。
還有人會說,這都什麼年代了,先後端分離啊,這些均可以經過一步步的改造來實現的。
(完)