1. 前言

Spring Security 实战干货:OAuth2第三方授权初体验一文中我先对OAuth2.0涉及的一些常用概念进行介绍,然后直接通过一个DEMO来让大家切身感受了OAuth2.0第三方授权功能。今天我们来一步一步分析这其中的机制。

2. 抓住源头

http://localhost:8082/oauth2/authorization/gitee

上面这个请求URL是我们在上一篇文章中提到的客户端进行第三方认证操作的起点,默认格式为{baseUrl}/oauth2/authorization/{clientRegistrationId},其中clientRegistrationId代表着一个第三方标识,可以是微信、支付宝等开放平台,这里为gitee。用户点击了这个请求后就开始了授权之旅。假如大家都是从零开始的小白,肯定是要从这个入口来一步一步探寻其中的机制的。Spring Security一定是拦截到了/oauth2/authorization后才启用了OAuth2相关的处理逻辑。那就去抓住这个源头!从源码中搜索嘛!IDEA 快捷键CTRL SHIFT R 就可以全局搜索结果了。

不出所料找到了三个地方,记下来一个一个看!

OAuth2AuthorizationRequestRedirectWebFilter

先来看第一个OAuth2AuthorizationRequestRedirectWebFilter,它实现了Spring Webflux的WebFilter接口,这显然是Webflux的东西,如果你用到Webflux的话这个会有用,但是不是现在我们用的。

DefaultOAuth2AuthorizationRequestResolver

第二个是干嘛的呢,从名称上看着是一个默认OAuth2授权请求解析器。有时候名称起的好就知道这个东西大致上干嘛的,不得不说优秀框架细节抓的很好。它实现了接口OAuth2AuthorizationRequestResolver:

public interface OAuth2AuthorizationRequestResolver {

   /**
* 从HttpServletRequest对象中解析封装 OAuth2AuthorizationRequest
*/
OAuth2AuthorizationRequest resolve(HttpServletRequest request); /**
* 从HttpServletRequest对象以及clientRegistrationId中解析封装 OAuth2AuthorizationRequest
*/
OAuth2AuthorizationRequest resolve(HttpServletRequest request, String clientRegistrationId); }

也就是说当我们请求/oauth2/authorization时,DefaultOAuth2AuthorizationRequestResolver 会从/oauth2/authorization对应的HttpServletRequest中提取数据封装到OAuth2AuthorizationRequest请求对象中做进一步使用。

注意/oauth2/authorization这个默认拦截标识也是可以自定义的。

OAuth2AuthorizationRequest

这里简单提一下OAuth2AuthorizationRequest 封装了我们上一文所描述的一些OAuth2相关概念参数,后续这个请求类我们会用到它。

public final class OAuth2AuthorizationRequest implements Serializable {
private static final long serialVersionUID = 520L;
private String authorizationUri;
private AuthorizationGrantType authorizationGrantType;
private OAuth2AuthorizationResponseType responseType;
private String clientId;
private String redirectUri;
private Set<String> scopes;
private String state;
private Map<String, Object> additionalParameters;
private String authorizationRequestUri;
private Map<String, Object> attributes;
// 其它方法略
}

OAuth2AuthorizationRequestRedirectFilter

就剩下这个线索了,一看到它继承了OncePerRequestFilter我就知道肯定是他了。甚至它的成员变量包含了用来解析OAuth2请求的OAuth2AuthorizationRequestResolver。到这里我们的路子就走对了,开始分析这个过滤器,下面是其核心过滤逻辑,这就是我们想要知道的OAuth2授权请求是如何被拦截处理的逻辑。

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException { try {
OAuth2AuthorizationRequest authorizationRequest = this.authorizationRequestResolver.resolve(request);
if (authorizationRequest != null) {
this.sendRedirectForAuthorization(request, response, authorizationRequest);
return;
}
} catch (Exception failed) {
this.unsuccessfulRedirectForAuthorization(request, response, failed);
return;
} try {
filterChain.doFilter(request, response);
} catch (IOException ex) {
throw ex;
} catch (Exception ex) {
// Check to see if we need to handle ClientAuthorizationRequiredException
Throwable[] causeChain = this.throwableAnalyzer.determineCauseChain(ex);
ClientAuthorizationRequiredException authzEx = (ClientAuthorizationRequiredException) this.throwableAnalyzer
.getFirstThrowableOfType(ClientAuthorizationRequiredException.class, causeChain);
if (authzEx != null) {
try {
OAuth2AuthorizationRequest authorizationRequest = this.authorizationRequestResolver.resolve(request, authzEx.getClientRegistrationId());
if (authorizationRequest == null) {
throw authzEx;
}
this.sendRedirectForAuthorization(request, response, authorizationRequest);
this.requestCache.saveRequest(request, response);
} catch (Exception failed) {
this.unsuccessfulRedirectForAuthorization(request, response, failed);
}
return;
} if (ex instanceof ServletException) {
throw (ServletException) ex;
} else if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
} else {
throw new RuntimeException(ex);
}
}
}

doFilterInternal对应的流程如下:

根据这个流程,如果要搞清楚Spring Security OAuth2是如何重定向到第三方的话就要深入研究sendRedirectForAuthorization方法,基于篇幅原因我会在下一篇进行分析。

3. 总结

今天我们从源头一步一步找到OAuth2授权的处理入口,并初步分析了几个关键组件的作用以及核心拦截器的拦截逻辑。后续我们将层层深入循序渐进地搞清楚其运作流程,不要走开,锁定:码农小胖哥 循序渐进学习Spring Security OAuth2 。

关注公众号:Felordcn 获取更多资讯

个人博客:https://felord.cn

Spring Security 实战干货:客户端OAuth2授权请求的入口的更多相关文章

  1. Spring Security 实战干货:OAuth2授权请求是如何构建并执行的

    在Spring Security 实战干货:客户端OAuth2授权请求的入口中我们找到了拦截OAuth2授权请求入口/oauth2/authorization的过滤器OAuth2Authorizati ...

  2. Spring Security 实战干货:OAuth2授权回调的处理机制

    1. 前言 上一文着重讲了当用户发起第三方授权请求是如何初始化OAuth2AuthorizationRequest授权请求对象以及如何通过过滤器进行转发到第三方的.今天我们接着这个流程往下走,来看看服 ...

  3. Spring Security 实战干货:OAuth2登录获取Token的核心逻辑

    1. 前言 在上一篇Spring Security 实战干货:OAuth2授权回调的核心认证流程中,我们讲了当第三方同意授权后会调用redirectUri发送回执给我们的服务器.我们的服务器拿到一个中 ...

  4. Spring Security 实战干货:OAuth2第三方授权初体验

    1. 前言 Spring Security实战干货系列 现在很多项目都有第三方登录或者第三方授权的需求,而最成熟的方案就是OAuth2.0授权协议.Spring Security也整合了OAuth2. ...

  5. Spring Security 实战干货: 简单的认识 OAuth2.0 协议

    1.前言 欢迎阅读 Spring Security 实战干货 系列文章 .OAuth2.0 是近几年比较流行的授权机制,对于普通用户来说可能每天你都在用它,我们经常使用的第三方登录大都基于 OAuth ...

  6. Spring Security 实战干货:图解Spring Security中的Servlet过滤器体系

    1. 前言 我在Spring Security 实战干货:内置 Filter 全解析对Spring Security的内置过滤器进行了罗列,但是Spring Security真正的过滤器体系才是我们了 ...

  7. Spring Security 实战干货:使用 JWT 认证访问接口

    (转载)原文链接:https://my.oschina.net/10000000000/blog/3127268 1. 前言 欢迎阅读Spring Security 实战干货系列.之前我讲解了如何编写 ...

  8. Spring Security 实战干货:实现自定义退出登录

    文章目录 1. 前言 2. 我们使用 Spring Security 登录后都做了什么 2. 退出登录需要我们做什么 3. Spring Security 中的退出登录 3.1 LogoutFilte ...

  9. Spring Security 实战干货:如何实现不同的接口不同的安全策略

    1. 前言 欢迎阅读 Spring Security 实战干货 系列文章 .最近有开发小伙伴提了一个有趣的问题.他正在做一个项目,涉及两种风格,一种是给小程序出接口,安全上使用无状态的JWT Toke ...

随机推荐

  1. 【代码审计】PHP代码审计---基础记录

    PHP伪协议 PHP伪协议事实上是其支持的协议与封装协议,支持的种类有以下12种. * file:// - 访问本地文件系统 * http:// - 访问 HTTP(s) 网址 * ftp:// - ...

  2. 浅谈 Java集合

    Java 集合 集合是对象的容器,定义了多个对象进行操作的常用方法,可实现数组的功能. Java集合类库所处位置:java.util.*. 与现代的数据结构类库的常见做法一样,Java集合类库也将接口 ...

  3. 通过VNC远程连接Linux实例

    无法使用Workbench和远程连接软件(例如PuTTY.Xshell.SecureCRT等)连接Linux实例时,您可以通过控制台的VNC远程连接实例,查看云服务器操作界面的实时状态. 前提条件 已 ...

  4. antd pro 下的文件下载

    概要 示例 后端 前端 直接显示图片 提供下载链接, 点击后下载 文件导出, 前端没有显示下载链接的位置 概要 前端上传文件的例子很多, 但是下载相关的例子不多, 主要是因为下载本身比较简单. 但是这 ...

  5. 多测师讲解seleniun_ ACTIONCHAUNS定位_高级讲师肖sir

    1.传统方法定位 2.模拟鼠标定位

  6. spring boot:spring security实现oauth2授权认证(spring boot 2.3.3)

    一,oauth2的用途? 1,什么是oauth2? OAuth2 是一个开放标准, 它允许用户让第三方应用访问该用户在某一网站上存储的私密资源(如头像.照片.视频等), 在这个过程中无须将用户名和密码 ...

  7. centos8平台使用journalctl管理systemd-journald日志

    一,systemd-journald的作用 1,什么是systemd-journald? systemd-journald 是 systemd 自带的日志系统,是一个收集并存储各类日志数据的系统服务. ...

  8. Linux文件系统和管理-2文件操作命令(下)

    移动和重命名文件 mv 命令可以实现文件或目录的移动和改名 剪切的效果 同一分区移动数据,速度很快:数据位置没有变化 不同分区移动数据,速度相对慢:数据位置发生了变化 格式 和cp基本一样 mv [O ...

  9. Linux命令提示符

    命令提示符:prompt [root@localhost ~]# 用户@主机名 所在目录 用户身份(#管理员 $普通用户) 显示提示符格式 Ubuntu sun@u18-2:~$ echo $PS1 ...

  10. Ubuntu Eclipse启动时报错:A Java RunTime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse. No java virtual machine was found after searching the following locations:

      此问题起于我在Ubuntu1004上装了两个版本的eclipse:Galieo+helios:卸载前者后出现启动不了eclipse的问题:在网上找了下,可以按如下过程进行解决: Eclipse 3 ...