简介
Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案。一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。
代码如下:
- 导入对应坐标,web+security
<!-- web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring安全控制 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
2.1 默认用户名: user,启动工程,控制台会输出,security随机生成的密码 如图:
2.2 访问项目根路径 localhost:8080,发现跳到了登录页
- 基本原理分析:
- SpringSecurity本质是一个过滤器链
- FilterSecurityInterceptor :权限过滤器,基本位于过滤链的最底部
- ExceptionTranslationFilter :异常过滤器,处理认证授权过程中抛出的异常
- UsernamePasswordAuthenticationFilter :对/login的POST请求做拦截,校验表单中用户名,密码。
-
两个重要接口
-
UserDetailsService:进行查询数据库账号密码的过程
- 创建类继承 UsernamePasswordAuthenticationFilter,重写三个方法
- 创建UserDetailsService实现类,编写查询数据库过程,返回User对象,这个User对象是security框架提供的
- PasswordEncoder:数据加密接口(加密密码)
-
UserDetailsService:进行查询数据库账号密码的过程
- SpringSecurity本质是一个过滤器链
-
设置登录的用户名和密码:三种方式
- 配置文件 applicaiton.yml:
spring: security: user: name: admin password: 123123 ```
- 配置类:编写配置类,继承WebSecurityConfigurerAdapter
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override//认证 protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 密码加密器,它实现了 PasswordEncoder 接口 BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); String password = passwordEncoder.encode("zhangsan"); auth.inMemoryAuthentication() //内存中进行校验 .withUser("zhangsan").password(password).roles("vip1"); } @Bean //由于加密时需要用到 PasswordEncoder接口,所以要放到容器中,否则报错 public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } }
- 自定义编写实现类 (重点、常用)
- 配置类:
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired //注入服务层, UserDetailsService userDetailsService; @Override//身份验证管理器生成器 protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } @Bean //由于加密时需要用到 PasswordEncoder接口,所以要放到容器中,否则报错 public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
- 服务层:这里应该查询数据库,因为麻烦所以不查了
@Service("userDetailsService") public class MyUserDetailsService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { // 1. 查看源码发现 Security的User类 需要传入用户名 密码 Collection 集合 // 2. 工具类中commaSeparatedStringToAuthorityList()方法创建 身份集合 List<GrantedAuthority> list = AuthorityUtils.commaSeparatedStringToAuthorityList("vip"); return new User("student",new BCryptPasswordEncoder().encode("student"),list); } }
- 配置类:
- 配置文件 applicaiton.yml: