簡介
SpringSecurity原理(一)——初探 SpringSecurity原理(二)——認證 SpringSecurity原理(三)——授權 SpringSecurity原理(四)——過濾器 SpringSecurity原理(五)——擴展與配置
之前使用Shiro的時候覺得有些繁瑣,最近開始用Spring Security的時候才發現和Spring Security一比,Shiro簡直對新手太友好了。
主要是Spring Security架構雖然比較清晰,但是它考慮的問題太多了,簡單的說就是Spring Security爲我們準備了大而全的解決方案。
而很多時候,可能我們並不需要那麼全面的解決方案。幾個簡單的例子,一個用戶認證,很可能我們只需要用戶名和密碼就夠用了。
但是Spring Security中設計得更像是Linux的用戶系統,考慮了用戶過期、用戶禁用、用戶密碼過期等等,最重要的是沒有給默認的實現,必須自己重寫我們不需要的方法,雖然並不是什麼難事,但是總有點不得勁,具體可以看org.springframework.security.core.userdetails.UserDetails接口。
Spring Security雖然繁雜,但是整個的架構還是比較清晰,下面我們就來簡單看一看Spring Security的原理。
前置知識
Spring Security主要是服務於Web應用,Spring Security也主要是通過Java的Filter來實現。
Java的Web應用兩大核心就是:
- Servlet
- Filter
很多朋友可能已經忘了在沒有SpringMVC之前被java的web.xml配置支配的恐懼。
如果對此沒有印象的朋友,或者完全沒有使用過的朋友,可以看下面的web.xml配置回憶一下,看還能不能記得每個配置的含義。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>terrible</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<filter>
<display-name>EcodingFilter</display-name>
<filter-name>EcodingFilter</filter-name>
<filter-class>vip.mycollege.filter.EnCodeFilter</filter-class>
<init-param>
<param-name>EncodeCoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EcodingFilter</filter-name>
<servlet-name>hello</servlet-name>
<url-pattern>*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class></servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
上面的配置還是隻是一個簡單的Servet和一個Filter。
Java Web的整個流程還簡單,就是Servelt容器,也就是Java Web服務器,如,Tomcat、Jetty等啓動的時候回去加載web.xml文件,解析裏面的配置,主要是Servlet和Filter,把url和Servlet、Filter對應上,這樣當接收都一個url請求的時候,就交個對應的Filter和Servlet去處理。
先Filter後Servlet的,Filter可以有多個,是鏈式結構,有優先級。
web.xml配置方式的最大的問題就是,url映射配置複雜,稍不小心就404。
後來有了SpringMVC就好了一些,只需要配置一個Servlet,都交給org.springframework.web.servlet.DispatcherServlet這個Servlet統一處理url的映射分發,Spring自己去解析Controller註解,把url和對應的方法對應,不用自己去配置url映射了。
再後來有了SpringBoot,簡直就起飛了,DispatcherServlet都不需要配置了,開箱即用。
雖然,不需要手動配置了,原理還是要了解一點,這裏我們只需要記住,Java的Web請求都是要先過Filter的,而這是Spring Security施展身手的地方。
簡單的示例
如果一上來就直接說一下抽象概念,很多朋友可能就放棄治療了。所以,我們先來一個簡單的入門級示例,在門口看一下Spring Security是個啥東西。
pom依賴
首先,要引入Spring Security依賴,如果使用SpringBoot,引入非常簡單
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/>
</parent>
<groupId>vip.oschool</groupId>
<artifactId>spsecurity</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spsecurity</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
配置文件
server:
port: 8081
spring:
security:
user:
name: tim
password: 111111
上面配置了一個用戶tim,密碼是111111,如果不配置,Spring Security會使用默認用戶,每次會生成隨機密碼。
控制器
添加一個簡單的控制器
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/index")
public class IndexController {
@RequestMapping("/hello")
public String hello(){
return "Hello World";
}
}
啓動類
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class StartApplication {
public static void main(String[] args) {
SpringApplication.run(StartApplication.class, args);
}
}
登錄界面
啓動之後,直接訪問:http://localhost:8081/index/hello
然後,就會被重定向到:http://localhost:8081/login
需要輸入用戶名和密碼,這個過程有一個專有名詞叫:認證,Authentication