【認證與受權】Spring Security自定義頁面

在前面的篇幅中,咱們對認證和受權流程大體梳理了一遍。在這個過程當中咱們一直都是使用系統生成的默認頁面,登陸成功後也是直接調轉到根路徑頁面。而在實際的開發過程當中,咱們是須要自定義登陸頁面的,有時還會添加各種驗證機制,在登陸成功後會跳轉至指定頁面,還會進行各類美化,甚至是先後端分離的方式。這時,就須要咱們對自定義登陸進行實現。html

本章節使用spring-security-custom-loginjava

1、工程準備

一、pom.xml

<?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

二、application.yml

server:
  port: 8080

spring:
  security:
    user:
      name: admin
      password: admin
      roles: ADMIN

很是的熟悉,端口、基礎用戶等信息spring

三、啓動類Application

@SpringBootApplication
public class SecurityLoginApplication {
    public static void main(String[] args) {
        SpringApplication.run(SecurityLoginApplication.class,args);
    }
}

2、自定義SecurityConfig

自定義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();
	}
  1. 對任何請求要求用戶已認證(通俗地講,用戶必須先登陸才能訪問任何資源);
  2. 啓用用戶名密碼錶單登陸認證機制;
  3. 啓用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()爲認證成功後跳轉的頁面地址

3、自定義頁面

在springboot中使用html頁面這裏就不過多贅述,通常狀況下在resource下新建templates文件下,將須要的頁面放到該文件下便可。個人路徑爲app

_resource
  |_templates
	|_login.html
	|_index.html

一、login.thml

<!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");
	}

二、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>
        <h2>Welcome <b th:text="${username}"></b></h2>
    </body>
</html>

這是個認證成功後的歡迎頁面,比較簡單,顯示當前登陸用戶便可

4、BaseContoller

上面咱們定義了各種路徑和請求地址,接下來咱們須要定義若是將這些頁面映射出來

@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";
    }
}

5、測試

到這裏咱們已經完成了一個簡單的自定義登陸頁面的改造了。固然,在實際的項目中須要自定義的東西還有不少不少,好比,當認證不經過時若是操做,當用戶退出登陸時若是操做,這些都沒有去實現。

還有人會說,這都什麼年代了,先後端分離啊,這些均可以經過一步步的改造來實現的。

(完)