SpringSecurity曾經在十年前非常火熱,只要是做權限系統,當時幾乎非用它不可,記得是在XML文件里一堆的配置。曾幾何時,Shiro冒了出來,以其簡潔和輕量的風格慢慢地捕獲了眾多碼農的心,從此SpringSecurity似乎成了歷史文物。
但事物總是在發展變化的,這兩年隨着 SpringBoot的興起,由於SpringSecurity與SpringBoot都是Spring家族成員,在整合上具備天然優勢,且SpringSecurity功能相對Shiro更加完善,對OAUTH認證支持得比較好,所以在微服務架構中又得到了廣泛應用。
在SpringBoot下使用SpringSecurity非常的簡單,只要保證在項目的classpath下引入了相應的jar包就可以了。啟動類上也無需添加什么,下面看一個SpringSecurity應用的最簡項目:
1. pom配置
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.2.RELEASE</version> </parent> <groupId>cn.xxx.yyyy</groupId> <artifactId>spring-security-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring-security-demo</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </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> </dependencies>
2. 啟動類
@SpringBootApplication public class App { public static void main( String[] args ) { SpringApplication.run(App.class, args) ; } }
3.application.properties或application.yml
沒配置任何內容
運行啟動類App后訪問 127.0.0.1:8080 ,出現如下頁面:
這說明請求被springSecurity攔截了,springSecurity開始發揮作用了。
一切看起來似乎很神奇,其實無非springBoot實例啟動時,發現類路徑下有相應的springSecurity的類,然后就自動幫我們加載了springSecurity的配置。
下面仔細分析下,跟我們在pom中引入的spring-boot-starter-web依賴有很大關系:
spring-boot-starter-web這個依賴不但引入了相關的 springMvc的jar , 還傳遞引入了 spring-boot-autoconfigure 這個jar ,如圖:
由於spring-boot-autoconfigure的jar中有 spring.factories文件,這個文件中提供了大量的配置類,是會被springboot框架自動解析處理的,其中就有和springSecurity相關的配置類 org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,它的源碼如下:
@Configuration @ConditionalOnClass(DefaultAuthenticationEventPublisher.class) @EnableConfigurationProperties(SecurityProperties.class) @Import({ SpringBootWebSecurityConfiguration.class, WebSecurityEnablerConfiguration.class, SecurityDataConfiguration.class }) public class SecurityAutoConfiguration { @Bean @ConditionalOnMissingBean(AuthenticationEventPublisher.class) public DefaultAuthenticationEventPublisher authenticationEventPublisher( ApplicationEventPublisher publisher) { return new DefaultAuthenticationEventPublisher(publisher); } }
通過源碼可知:
1. 會在類路徑下查找DefaultAuthenticationEventPublisher類(存在於spring-secrity-core-x.y.z.RELEASE jar中),如果存在這個類 ,SecurityAutoConfiguration這個配置類就會起作用。
2 . 會導入三個配置類 SpringBootWebSecurityConfiguration.class , WebSecurityEnablerConfiguration.class, SecurityDataConfiguration.
3. SpringBootWebSecurityConifguration類,這里真正引入了SpringSecurtiy的默認配置類WebSecurityConfigurerAdapter,當然首先會在類路徑下類路徑下查找是否
WebSecurityConfigurerAdapter的子類的bean的配置,如果沒有就使用WebSecurityConfigurerAdapter的默認配置
@Configuration @ConditionalOnClass(WebSecurityConfigurerAdapter.class) @ConditionalOnMissingBean(WebSecurityConfigurerAdapter.class) @ConditionalOnWebApplication(type = Type.SERVLET) public class SpringBootWebSecurityConfiguration { @Configuration @Order(SecurityProperties.BASIC_AUTH_ORDER) static class DefaultConfigurerAdapter extends WebSecurityConfigurerAdapter { } }
此外,spring-boot-starter-security 這個依賴的作用也不可忽視 , 它保證需要的jar被引入: