SpringSecurity是一個安全框架,使用它可讓咱們的系統變得安全一點,它能夠對登錄系統的用戶進行驗證和受權
一個安全的系統須要作的事情不少,好比:防SQL注入、XSS攻擊、CSRF等等,
還須要對每個登錄系統的用戶進行權限認證,即決定了每一個用戶能作什麼、不能作什麼
在權限管理以前,還得對用戶進行受權,受權後根據權限區分用戶
授予和權限認證就是SpringSecurity主要作的事情
很重要的一點是,在SpringBoot中使用,可讓本來對開發者來講複雜的SpringSecurity變得簡單易用
固然SpringSecurity也有很明顯的缺點,就是導入依賴以後,就默認實現了不少奇奇怪怪的東西,讓人感受莫名其妙html
這裏是直接在SpringBoot中集成的java
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency>
二、建立一個Controller類測試一下,因此還要導入web依賴包web
SecretController.javaspring
1 import org.springframework.web.bind.annotation.GetMapping; 2 import org.springframework.web.bind.annotation.RestController; 3 4 @RestController 5 public class SecretController { 6 @GetMapping("/secret") 7 public String getSecret(){ 8 return "this is secret"; 9 } 10 }
而後運行項目咱們直接訪問 http://localhost:8080/secret ,會發現頁面重定向了,跳轉到了一個登錄頁面數據庫
咱們甚至沒有設置登錄用戶名和密碼apache
這個地方SpringSecurity默認的用戶名是user,密碼是動態生成的,在日誌中會顯示安全
這就是SpringSecurity強大的地方,僅僅是導入了依賴包,就默認進行了登錄驗證,固然這也是弊端,由於咱們根本不知道它是怎麼配置的。mvc
上面是SpringSecurity爲咱們默認配置的一個登錄頁面,下面咱們本身進行配置app
這裏是整個例子的文件結構還有pom.xml,以及使用了thymeleaf,因此要導入依賴框架
文件結構
pom.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>org.example</groupId> 8 <artifactId>SecurityTest</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 11 <parent> 12 <groupId>org.springframework.boot</groupId> 13 <artifactId>spring-boot-starter-parent</artifactId> 14 <version>2.5.2</version> 15 </parent> 16 17 <dependencies> 18 <dependency> 19 <groupId>org.springframework.boot</groupId> 20 <artifactId>spring-boot-starter-web</artifactId> 21 </dependency> 22 23 <dependency> 24 <groupId>org.springframework.boot</groupId> 25 <artifactId>spring-boot-starter-thymeleaf</artifactId> 26 </dependency> 27 28 <dependency> 29 <groupId>org.springframework.boot</groupId> 30 <artifactId>spring-boot-starter-security</artifactId> 31 </dependency> 32 </dependencies> 33 34 <properties> 35 <maven.compiler.source>8</maven.compiler.source> 36 <maven.compiler.target>8</maven.compiler.target> 37 </properties> 38 39 </project>
首先咱們要本身建立一個login頁面,以及登陸之後訪問的頁面
login.html
1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org" 3 xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> 4 <head> 5 <title>Spring Security Example </title> 6 </head> 7 <body> 8 <div th:if="${param.error}"> 9 Invalid username and password. 10 </div> 11 <div th:if="${param.logout}"> 12 You have been logged out. 13 </div> 14 <form th:action="@{/login}" method="post"> 15 <div><label> User Name : <input type="text" name="username"/> </label></div> 16 <div><label> Password: <input type="password" name="password"/> </label></div> 17 <div><input type="submit" value="Sign In"/></div> 18 </form> 19 </body> 20 </html>
hello.html
1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org" 3 xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> 4 <head> 5 <title>Hello World!</title> 6 </head> 7 <body> 8 <h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1> 9 10 </body> 11 </html>
而後再MVC裏面配置一下這兩個頁面,才能夠經過url進行訪問,MVC的配置須要實現WebMvcConfigurer接口
MvcConfig.java
1 import org.springframework.context.annotation.Configuration; 2 import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; 3 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 4 5 @Configuration 6 public class MvcConfig implements WebMvcConfigurer { 7 8 @Override 9 public void addViewControllers(ViewControllerRegistry registry) { 10 11 registry.addViewController("/").setViewName("login"); 12 registry.addViewController("/hello").setViewName("hello"); 13 registry.addViewController("/login").setViewName("login"); 14 } 15 }
而後咱們須要進行SpringSecurity的配置,定義頁面訪問請求時,用戶須要哪些權限,須要繼承WebSecurityConfigurerAdapter類進行配置
如今配置中本身定義了一個用戶(在實際項目中從數據庫獲取),而再也不是由SpringSecurity默認定義
WebSecurityConfig.java
1 import org.springframework.context.annotation.Bean; 2 import org.springframework.context.annotation.Configuration; 3 import org.springframework.security.config.annotation.web.builders.HttpSecurity; 4 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 5 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 6 import org.springframework.security.core.userdetails.User; 7 import org.springframework.security.core.userdetails.UserDetails; 8 import org.springframework.security.core.userdetails.UserDetailsService; 9 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 10 import org.springframework.security.crypto.password.PasswordEncoder; 11 import org.springframework.security.provisioning.InMemoryUserDetailsManager; 12 13 @Configuration 14 @EnableWebSecurity 15 public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 16 /* 17 @EnableWebSecurity註解讓springsecurity集成springmvc 18 */ 19 @Override 20 protected void configure(HttpSecurity http) throws Exception { 21 /* 22 定義了哪些路徑訪問是須要權限的,哪些不用 23 /和/login兩個url是不須要權限就能夠訪問的 24 /hello須要有「USER」權限纔可以訪問 25 */ 26 http.authorizeRequests() 27 .antMatchers("/hello") 28 .hasRole("USER") 29 .and() 30 .formLogin() 31 .loginPage("/login") 32 .permitAll(); 33 } 34 35 36 @Bean 37 public PasswordEncoder passwordEncoder(){ 38 /* 39 聲明一個加密工具的Bean,供用戶進行加密時調用 40 */ 41 return new BCryptPasswordEncoder(); 42 } 43 44 @Bean 45 @Override 46 protected UserDetailsService userDetailsService() { 47 /* 48 設置了一個預先存儲在系統中的用戶 49 賦予用戶「USER」角色權限,纔可以訪問hello頁面 50 */ 51 String username = "user"; 52 String password = "password"; 53 UserDetails user = User.withUsername(username).password(new BCryptPasswordEncoder().encode(password)).roles("USER").build(); 54 return new InMemoryUserDetailsManager(user); 55 } 56 }
如今運行項目,在沒有登陸以前,訪問/hello會被重定向到login頁面,登陸以後就能訪問hello頁面了
若是把上面代碼裏,用戶的角色權限「USER」改爲其餘的,登陸以後訪問\hello則會拋出403錯誤,由於權限不夠