上一篇:Spring Security OAuth2.0 认证协议【6】准备 RESTful API:swagger、WireMock
下一篇:https://blog.csdn.net/LawssssCat/article/details/105296640
至此,前面的环境搭建,接口准备结束,进入 Spring Security 正题。
代码下载:https://github.com/LawssssCat/v-security/tree/v2.0
内容简介
会以表单登录为起点,逐渐添加概念和扩展场景,最终形成较为复杂的案例。
spring security 默认就是 http basic 认证,我们只需要:
重新打开 spring security,并运行程序
只要添加了 spring security 就会默认开启 httpbasic 模式,之前开发 api 关了,现在打开,并运行。
测试
访问: http://localhost:8080/user/1
就到了我们熟悉的 httpBasic 认证了
如果看不到 http basic 认证,
而是 page not found
只需要去到全局处理,把 自定义的 ErrorController 实现类去掉即可
(当时是处理 404 请求,而开启 security 后,404 会到认证界面,且security优先级更低,因此会到 上面界面,而不是security 的 http basic 认证。如果两个都想开,那么调下优先级即可)
提高代码重用性,所以所有跟认证授权相关的代码会写在 v-security-browser 里面,而 v-security-demo 只是使用 browser 的写好安全模块。
编写安全配置类
在 v-security-borwser 模块中
创建 package:cn.vshop.security.browser
创建类 BrowserSecurityConfig
package cn.vshop.security.browser;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* {@link WebSecurityConfigurerAdapter}:
* spring security 提供的 {@link WebSecurity} 适配器
* 一个帮我们实现了大部分{@link WebSecurityConfigurer}接口的抽象类
*
* 提供了可以重写的configure方法,在方法内可以装配自定义的Filter配置
* 其指定的Filter会被生产为{@link FilterChainProxy}
* 最终以{@link DelegatingFilterProxy}作为spring Security Filter Chain起作用
*
* 即:其实现是用来配置spring Security Filter Chain的
*
*
* @author alan smith
* @version 1.0
* @date 2020/4/3 12:15
*/
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// 指定身份认证方式为表单
http.formLogin()
.and()
// 并且认证请求
.authorizeRequests()
// 全部请求,都需要认证
.anyRequest().authenticated();
}
}
启动并访问
http://localhost:8080/user/1
Spring Security 其实就是一堆的过滤器链(如下图绿色部分)
其中
UsernamePasswordAuthenticationFilter
对应的是表单 登录BasicAuthenticationFilter
对应的则是 HttpBasic 登录身份认证 流程
UsernamePasswordAuthenticationFilter
登录BasicAuthenticationFilter
处理请求拦截 流程
在交给 (上图绿色)认证过滤器处理后,最终会来到 FilterSecurityInterceptor
拦截器 (如下图橙色)
(过滤器、拦截器知识在 第四章 末尾有讲)
FilterSecurityInterceptor
可以理解为最终的守门人,在他身后的,便是我们编写的 REST API 服务了。
能否真正访问到 这些服务,全由 FilterSecurityInterceptor
决定。
错误处理 流程
如果 FilterSecurityInterceptor
判断了不能访问,会根据不同访问的原因抛出响应的异常。
这些异常的处理拦截器是位于 FilterSecurityInterceptor
前面的 ExceptionTranslationFilter
(如下图蓝色)
而我们要做的 spring Security 开发,就是添加 绿色的过滤器
眼见为实
有了上面原理,下面我们打断点,跟着源码走一遍
第一个断点
打在 UserController 的 query 方法上,代表最终认证成功
第二断点
FilterSecurityInterceptor
(示意图中的橙色) 的 invok 方法上打断点
(打在 token 上,代表认证结束)
第三个断点
ExceptionTranslationFilter
上打断点,看出现认证异常后的处理
第四个断点
打在 UsernamePasswordAuthenticationFilter 上,看看如何密码认证的
(我们后面要自定义,即覆盖这里的操作的)
程序 debug 运行起来 ,依次访问,观测运行流程
访问: http://localhost:8080/user
因为没有携带登录信息,所以直接通过(原理图中)绿色的过滤器,来到了(原理图中)蓝色的异常过滤器,并且准备往下面的拦截器传递
来到 FilterSecurityInterceptor 进行判断能否访问后面的请求
(因为没有登录,所以,拿到token 这一步会报错,异常会返回到 上面的 ExceptionTranslationFilter)
捕获到了异常,然后就是重定向到登录页面
直接放行,前端就会显示登录页面
输入用户名密码登录
会来到 UsernamePasswordAuthenticationFilter 的 attemptAuthentication 方法
继续往下,就进到我们写的 api 里面了