1. Spring Security简介
Spring Security是为Spring 应用程序提供声明式安全保护的安全性框架,所谓的安全框架就是对应用进行安全保护,包括认证(Authentication)和授权(Authorization)两大功能;认证和授权两个含义不同的术语;
- 认证:是指验证某个用户是否为系统中的合法主体,比如通过提供用户名密码,或者令牌等凭证来证明用户是否为系统的合法用户;
- 授权:验证用户是否有权限执行某个操作,比如对某个请求的是否具有访问权限,对文件是否具有读写权限等
2. 常用的安全认证框架
除了Spring Security框架,常用的安全认证框架和shiro框架;相比Spring Security框架,shiro框架的的最大优势就是简单易用、易理解,且不跟具体的框架和容器绑定;
本文主要介绍Spring Security框架,Spring Security框架除了不能脱离shiro框架之外,shiro有的功能它都有,另外Spring Security还号称具有比shiro更高的权限控制粒度。而且Spring Security对OAuth(一个基于令牌的安全验证和授权框架)也有良好的支持,而shiro则需要自己手动实现;
如果需要快速的开发一个小型的非Spring框架项目,建议使用shiro框架,如果开发Spring 项目,尤其是时下流行的基于Spring Boot的微服务项目,要实现单点登录(SSO)等功能,建议使用Spring Security,从Spring Security的毕竟有Spring的加持,能够提供对Spring全家桶的无缝衔接。
3. 快速搭建
Spring Boot + Spring Security,使用内存存储用户(使用数据库表的参见)
代码地址: https://github.com/xdouya/Spring-Security-demo/tree/master/01-memory-security
Spring Security配置
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasAnyRole("admin")
.antMatchers("/vip/**").hasAnyRole("vip")
.antMatchers("/user/**").hasAnyRole("user")
.anyRequest().authenticated()
.and().formLogin()
.and().httpBasic();
}
@Override
@Bean
public UserDetailsService userDetailsService() {
InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
userDetailsManager.createUser(User.builder().username("admin").password("{bcrypt}" + bCryptPasswordEncoder.encode("088114")).
roles("admin").build());
userDetailsManager.createUser(User.builder().username("vip").password("{bcrypt}" + bCryptPasswordEncoder.encode("088114"))
.roles("vip").build());
userDetailsManager.createUser(User.builder().username("user").password("{bcrypt}" + bCryptPasswordEncoder.encode("088114"))
.roles("user").build());
return userDetailsManager;
}
/**
* 根据自动匹配密码编码器
* @return PasswordEncoder
*/
@Bean
public PasswordEncoder passwordEncoder(){
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
}
下图是Spring Security官网给出的一个认证过程;
- AuthenticationManager:认证管理器,管理Spring Security的过滤器如何实现认证;在Spring Security中最常见的实现为ProviderManager;
- ProviderManager:通过委托AuthenticationProvider接口的Authentication authenticate(Authentication authentication)方法来实现认证;
- DaoAuthenticationProvider:AuthenticationProvider的一个常用实现,DaoAuthenticationProvider通过UserDetailService来查找用户信息,通过PasswordEncoder进行编码后的一个密码比对
- UserDetailService:UserDetailsService 用户名,密码,以及其他属性的查找,Spring Security提供内存以及JDBC实现;本篇使用的是InMemoryUserDetailsManager为基于内存的实现,下篇介绍基于数据库的用户存储实现使用JDBC实现JdbcUserDetailsManager;
编写启动类以及控制器方法
- 控制器方法
/**
* @author caiwl
* @date 2020/8/9 14:05
*/
@RestController
public class HelloController {
@GetMapping("/")
public String hello(){
return "hello, wellcome";
}
@GetMapping("/admin/hello")
public String helloAdmin(){
return "hello admin";
}
@GetMapping("/vip/hello")
public String helloVip(){
return "hello vip";
}
@GetMapping("/user/hello")
public String helloUser(){
return "hello user";
}
}
- 启动类
@SpringBootApplication
public class MemoryApplication {
public static void main(String[] args) {
SpringApplication.run(MemoryApplication.class, args);
}
}
4. 测试
访问http://localhost:8080 会弹出Spring Security自带的默认登录界面,输入账号密码即可访问;
实际使用过程中,用户信息一般都不会存储在内存之中,而是存储在数据库中;
下一篇,介绍Security(二)基于数据库认证鉴权解决方案