1.简介
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
2.入门案例(基于SpringBoot)
①创建一个SpringBoot项目,我习惯先创建maven然后导入相关jar包
②导入相关依赖
<?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.6.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.qbb.springsecurity</groupId> <artifactId>security01</artifactId> <version>0.0.1-SNAPSHOT</version> <name>security01</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-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
③修改SpringBoot核心配置文件application.yml
server: port: 9001
④编写主启动类
package com.qbb.springsecurity.security01; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Security01Application { public static void main(String[] args) { SpringApplication.run(Security01Application.class, args); } }
⑤编写controller层
package com.qbb.springsecurity.security01.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author QiuQiu&LL (博客:https://www.gaodi.net/qbbit) * @version 1.0 * @date 2022-02-26 11:39 * @Description: */ @RestController @RequestMapping("/test") public class TestController { @GetMapping("/hello") public String hello() { return "hello security!!!"; } }
测试
默认的username:admin,密码是IDEA控制台输出的password:Using generated security password: af1d28f2-1fde-4a68-a52e-85b7d3055a6d
3.SpringSecurity基本原理
SpringSecurity本质是一个过滤器链,因为我用的是SpringBoot开发,所以SpringBoot已经做了很多的自动配置 https://docs.spring.io/spring-security/site/docs/5.3.4.RELEASE/reference/html5/#servlet-hello
4.SpringSecurity Web权限方案
①基于配置文件的方式
spring: security: user: password: qiuqiu name: qiuqiu
②基于配置类的方式
package com.qbb.springsecurity.security01.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; /** * @author QiuQiu&LL (博客:https://www.gaodi.net/qbbit) * @version 1.0 * @date 2022-02-28 18:05 * @Description: */ @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); String password = bCryptPasswordEncoder.encode("123"); auth.inMemoryAuthentication().withUser("qiuqiu").password(password).roles("admin"); } @Bean public PasswordEncoder getPasswordEncoder() { return new BCryptPasswordEncoder(); } }
③自定义实现类
package com.qbb.springsecurity.security01.config; import com.qbb.springsecurity.security01.service.MyUserDetailService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; /** * @author QiuQiu&LL (博客:https://www.gaodi.net/qbbit) * @version 1.0 * @date 2022-02-28 18:05 * @Description: */ @Configuration public class SecurityConfigTest extends WebSecurityConfigurerAdapter { @Qualifier("myUserDetailService") @Autowired MyUserDetailService myUserDetailService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(myUserDetailService).passwordEncoder(getPasswordEncoder()); } @Bean public PasswordEncoder getPasswordEncoder() { return new BCryptPasswordEncoder(); } }
package com.qbb.springsecurity.security01.service; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import java.util.List; /** * @author QiuQiu&LL (博客:https://www.gaodi.net/qbbit) * @version 1.0 * @date 2022-02-28 18:26 * @Description: */ @Service("myUserDetailService") public class MyUserDetailService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("role"); return new User("mary", new BCryptPasswordEncoder().encode("123"), auths); } }
工作中大部分使用第三种使用方式