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被引入: