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


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

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

一、工程准備

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,也是官方推薦的做法。

2、application.yml

server:
  port: 8080

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

非常的熟悉,端口、基礎用戶等信息

3、啟動類Application

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

二、自定義SecurityConfig

自定義SecurityConfig需繼承WebSecurityConfigurerAdapter並重寫相關配置即可,由於今天只涉及到自定義頁面的信息,所以我們只需要重寫configure(HttpSecurity http) 方法即可。在重寫這個方法前,我們先來看一下原來這個方法是干什么的。

	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();
    }
}

我們發現其實和缺省方法中並沒有太大的差別,只有三處的變化

  • loginPage()中將指定自定義登錄頁面的請求路徑
  • loginProcessingUrl() 為認證的請求接口,也就是我們常說的form表單中的action。如果不指定,將采用loginPage中的值。
  • defaultSuccessUrl()為認證成功后跳轉的頁面地址

三、自定義頁面

在springboot中使用html頁面這里就不過多贅述,一般情況下在resource下新建templates文件下,將需要的頁面放到該文件下即可。我的路徑為

_resource
  |_templates
	|_login.html
	|_index.html

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

2、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>

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

四、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";
    }
}

五、測試

到這里我們已經完成了一個簡單的自定義登錄頁面的改造了。當然,在實際的項目中需要自定義的東西還有很多很多,比如,當認證不通過時如果操作,當用戶退出登錄時如果操作,這些都沒有去實現。

還有人會說,這都什么年代了,前后端分離啊,這些都可以通過一步步的改造來實現的。

(完)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM