SpringBoot 整合 SpringSecurity + MySQL + JWT 附原始碼,廢話不多直接盤
SpringBoot已經為使用者採用預設設定,只需要引入pom依賴就能快速啟動Spring Security。
目的:驗證請求使用者的身份,提供安全存取
優勢:基於Spring,設定方便,減少大量程式碼
permitAll()
表示所匹配的 URL 任何人都允許存取。authenticated()
表示所匹配的 URL 都需要被認證才能存取。anonymous()
表示可以匿名存取匹配的 URL 。和 permitAll() 效果類似,只是設定為 anonymous() 的 url 會執行 filter 鏈中denyAll()
表示所匹配的 URL 都不允許被存取。rememberMe()
被「remember me」的使用者允許存取 這個有點類似於很多網站的十天內免登入,登陸一次即可記住你,然後未來一段時間不用登入。fullyAuthenticated()
如果使用者不是被 remember me 的,才可以存取。也就是必須一步一步按部就班的登入才行。hasAuthority(String)
判斷使用者是否具有特定的許可權,使用者的許可權是在自定義登入邏輯hasAnyAuthority(String ...)
如果使用者具備給定許可權中某一個,就允許存取hasRole(String)
如果使用者具備給定角色就允許存取。否則出現 403hasAnyRole(String ...)
如果使用者具備給定角色的任意一個,就允許被存取hasIpAddress(String)
如果請求是指定的 IP 就執行存取。可以通過 request.getRemoteAddr() 獲取 ip 地址Pom 檔案中新增
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<?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>vipsoft-parent</artifactId>
<groupId>com.vipsoft.boot</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>vipsoft-security</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.7</version>
</dependency>
<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-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
執行後會自動生成 password 預設使用者名稱為: user
預設設定每次都啟動專案都會重新生成密碼,同時使用者名稱和攔截請求也不能自定義,在實際應用中往往需要自定義設定,因此接下來對Spring Security進行自定義設定。
在記憶體中(簡化環節,瞭解邏輯)設定兩個使用者角色(admin和user),設定不同密碼;
同時設定角色存取許可權,其中admin可以存取所有路徑(即/*),user只能存取/user下的所有路徑。
自定義設定類,實現WebSecurityConfigurerAdapter
介面,WebSecurityConfigurerAdapter
介面中有兩個用到的 configure()方法,其中一個設定使用者身份,另一個設定使用者許可權:
SecurityConfig
package com.vipsoft.web.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 設定使用者身份的configure()方法
*
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
//簡化操作,將使用者名稱和密碼存在記憶體中,後期會存放在資料庫、Redis中
auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder)
.withUser("admin")
.password(passwordEncoder.encode("888"))
.roles("ADMIN")
.and()
.withUser("user")
.password(passwordEncoder.encode("666"))
.roles("USER");
}
/**
* 設定使用者許可權的configure()方法
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
//設定攔截的路徑、設定哪類角色可以存取該路徑
.antMatchers("/user").hasAnyRole("USER")
.antMatchers("/*").hasAnyRole("ADMIN")
//設定登入介面,可以新增自定義介面, 沒新增則用系統預設的介面
.and().formLogin();
}
}
新增介面測試用
package com.vipsoft.web.controller;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DefaultController {
@GetMapping("/")
@PreAuthorize("hasRole('ADMIN')")
public String demo() {
return "Welcome";
}
@GetMapping("/user/list")
@PreAuthorize("hasAnyRole('ADMIN','USER')")
public String getUserList() {
return "User List";
}
@GetMapping("/article/list")
@PreAuthorize("hasRole('ADMIN')")
public String getArticleList() {
return "Article List";
}
}