Version: Next
认识SpringSecurity
Spring Security 是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,他可以实现强大的Web安全控制,对于安全控制,我们仅需要引入 spring-boot-starter-security 模块,进行少量的配置,即可实现强大的安全管理!
记住几个类:
WebSecurityConfigurerAdapter
:自定义Security策略AuthenticationManagerBuilder
:自定义认证策略 源码用到适配器模式
、建造者模式
@EnableWebSecurity
:开启WebSecurity模式
Spring Security的两个主要目标是 “认证” 和 “授权”(访问控制)。
“认证”(Authentication)
身份验证是关于验证您的凭据,如用户名/用户ID和密码,以验证您的身份。
身份验证通常通过用户名和密码完成,有时与身份验证因素结合使用。
“授权” (Authorization)
授权发生在系统成功验证您的身份后,最终会授予您访问资源(如信息,文件,数据库,资金,位置,几乎任何内容)的完全权限。
这个概念是通用的,而不是只在Spring Security 中存在。
认证和授权
授权
引入SpringSecurity依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>可以看到SpringSecurity依赖AOP
编写SpringSecurity配置类
SecurityConfig
,继承WebSecurityConfigurerAdapter
- 添加
@EnableWebSecurity
注解 - 重写
configure(HttpSecurity http)
- 模拟需求:
- 首页所有人可以访问
- 功能页具有对应权限的人才能访问
//AOP 开闭原则@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {//认证请求.授权请求.允许所有人.授权请求.具有身份http.authorizeRequests().antMatchers("/").permitAll().antMatchers("/level1/**").hasRole("vip1").antMatchers("/level2/**").hasRole("vip2").antMatchers("/level3/**").hasRole("vip3");}}再次访问网站,会发现可以访问首页,但功能页403 请求拒绝,权限不足
添加代码,让没有权限的人被跳转到登录页面
@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {//认证请求.授权请求.允许所有人.授权请求.具有身份http.authorizeRequests().antMatchers("/").permitAll().antMatchers("/level1/**").hasRole("vip1").antMatchers("/level2/**").hasRole("vip2").antMatchers("/level3/**").hasRole("vip3");//没权限就跳转到登录页面http.formLogin();}}问题
为什么formLogin方法能让我们直接跳到login.html?
查看源码,它会自动去
/login
路由- 添加
认证
重写configure(AuthenticationManagerBuilder auth)
- 按照
.withUser().password().roles()
的顺序写 - 多个用户之间用
.and()
连接 .roles()
支持可变长度参数
//认证
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("Alice").password("123456").roles("vip2","vip3")
.and()
.withUser("root").password("root").roles("vip1","vip2","vip3");
}
测试,报错,说密码未加密
There is no PasswordEncoder mapped for the id "null"
添加密码加密,有各种XxxPasswordEncoding
可供使用
//认证
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("Alice")
.password(new BCryptPasswordEncoder().encode("123456"))
.roles("vip2", "vip3")
.and()
.withUser("root")
.password(new BCryptPasswordEncoder().encode("root"))
.roles("vip1", "vip2", "vip3");
}