上一篇:https://blog.csdn.net/LawssssCat/article/details/105336356
Spring Social 官网(旧的):https://projects.spring.io/spring-social/
Spring Social 官方文档:Spring Social Reference
OAuth协议简介
- OAuth协议要解决的问题
- OAuth协议中的各种角色
- OAuth协议运行流程
OAuth 协议要解决的问题
设想:本地平台访问用户在第三方平台上的数据。
如果直接询问用户第三方平台的账号密码会有很多问题:
(假设用户愿意给出第三方平台的账号密码)
- 本地应用可以访问用户在微信上的所有数据
(加大本地平台数据的管理成本) - 用户只有修改密码,才能收回授权
(但是,若授权给很多平台,一旦修改密码,其他平台授权也会被收回,加大用户管理授权的成本) - 密码泄露的可能性大大提高
<mark>OAuth协议为了解决这个问题诞生的</mark>
(示意图)
OAuth协议规定
- 访问第三方平台数据不再依靠用户名和密码,而是使用令牌
- 令牌上可以规定访问数据的权限
- 令牌上可以设定有效时间
OAuth 协议中的各种角色
三个主角
- Provider 服务提供商
<mark>谁提供令牌,谁就是服务提供商</mark> - Resource Owner 资源所有者
用户 - Client 第三方应用
希望吧服务提供商的用户(数据)变为自己(可操作)的数据
Provider内部还有 两个角色
- Authorization Server 认证服务器
作用是:认证用户的身份,并产生令牌 - Resource Server 资源服务器
作用有两:保存用户的资源、验证令牌(最终Client发送临牌是发往Resource Server的)
OAuth 协议运行流程
- 用户(Resource Owner)访问第三方应用(Client)
- 第三方应用(Client)询问用户(Resource Owner)是否向服务提供商(Provider)发送授权请求
- 用户(Resource Owner)同意发送授权请求
- 第三方应用(Client)向服务提供商(Provider)的认证服务器(Authorization Server)发送令牌申请请求
- 认证服务器(Authorization Server)认证通过后,向第三方应用(Client)发放令牌
- 第三方应用(Client)携带令牌,向服务提供商(Provider)的资源服务器(Resource Server)申请资源
- 资源服务器(Resource Server)校验令牌无误,开放资源给第三方应用(Client)
同意授权有四种方式
-
授权码模式(authorization code)
微信、qq、京东、淘宝。。。大多用此类授权模式 -
密码模式(resource owner password credentials)
-
客户端模式(client credentials)
-
简化模式(implicite)
客户端模式、简化模式不介绍,自己了解
授权码模式详细流程
(下图)如果第三方应用需要用户同意授权,会将用户导向认证服务器
(下图)如果用户同意授权,会将用户导回到第三方应用,<mark>同时携带授权码</mark>
(导去哪里,和导回到哪里,是Client和Provider事先商量好的)
而第三方应用Client得到授权码后,<mark>会携带授权码访问认证服务器,申请令牌</mark>
认证服务器收到Client携带了授权码的令牌申请请求,会校验授权码是否本地之前发出去的授权码,如果是,就发放令牌
为什么叫授权码模式
- <mark>因为这个模式过程中会产生一个授权码</mark>,这个在其他模式中没有
(除了简化模式)- 其次,用户同意授权的动作是在服务提供商(Provider)上完成的
(其他模式均是在Client上完成的)
为什么不直接发送令牌
直接发送令牌的模式就是简化模式(implicite),这种模式是给一些简单的仅由脚本支撑的网站做授权用的
(因为那些网站没有服务器,因此不能发送授权码到服务器,只能发送令牌到一个浏览器页面,让浏览器页面上的脚本获取令牌)
所以换而言之,直接发送令牌的模式通过前端脚本也能完成,就容易被XSS攻击
【整理】cookies、攻击(xss、csrf)、防御(stp、sop)、开发(JSONP、WebSockets)
第三方登录(Spring Social 所需要的接口)
续上图,Client 可以通过令牌获取用户信息,并且可以根据用户信息构建认证信息(Authentication)并放入 SecurityContext 中了
(这也是第三方登录的基本原理)
Spring Security 实现第三方登录是通过在过滤链上添加 SocialAuthenticationFilter (下图)
当过滤到第三方登录请求,就引导把上面流程走完
ServiceProvider 接口
ServiceProvider 接口充当服务提供商,通过这个接口的实现,向实现的Provider通信。
SpringSecurity 提供了 AbstractOAuth2ServiceProvider 简化实现配置
这里涉及到 OAuth2,上面讲的所有流程也是基于OAuth2的。
OAuth1国外也有用,如:Twitter、LinkedIn
而国内基本是用OAuth2了。
所以下面就只讲OAuth2了。
OAuthOperations 接口
OAuthOperations包括了OAuth2整个流程的2到5步。
(将用户引导到Provider ⇒ Provider发送令牌)
有一个默认的实现 OAuth2Template
Api 接口
Client 获取 Provider 中用户信息的接口。
因为各种情况都有,因此只提供了 AbstractOAuth2ApiBinding 的抽象实现
Connection、ConnectionFactory接口
- Connection 封装前面6个流程下来,得到的用户信息
有一个实现 OAuth2Connection - ConnectionFactory 创建 Connection
有一个实现 OAuth2ConnectionFactory
ApiAdapter 接口
每个服务提供商的用户数据的数据结构是不一样的。
而每个写好的Connection的数据接口是不变的。
<mark>ApiAdapter 做的就是两种数据结构的适配</mark>
UsersConnectionRepository接口和UserConnection数据库表
-
UserConnection数据库表建立Provider用户和Client用户关系的映射。
如:
指明Provider服务器上的“张珊”用户,是Client服务器中的“老婆”用户 -
UsersConnectionRepository 用于操作UserConnection表
实现类 JdebUsersConnectionRepository
Spring Social
官网(旧的):https://projects.spring.io/spring-social/
2018年7月,随着 Spreing Security 5 的发布和 Spring Social Api 接口实现的臃肿,Spring Social最终被废弃,功能被合并到中Spring Security 5 中。
参考:Spring Social End of Life Announcement
但作为学习OAuth2还是有一定借鉴作用。
| Name | Description |
|---|---|
| spring-social-core | 项目核心,包含主干逻辑 Spring Social’s Connect Framework and OAuth client support. |
| Spring Social Facebook | 连接 Facebook 的已经写好的实现 |
| Spring Social Twitter | |
| Spring Social LinkedIn | |
| Spring Social GitHub | |
| Spring Social TripIt |
在(旧的)官网中还能看到其他的基于 Spring Social Core 做的一些实现
可以看到,这里已经有微博(weibo)的实现,而没有QQ、微信的实现。
所以下面就来实现QQ和微信的第三方登录
侧重点
- QQ:OAuth实现相对标准,重点掌握OAuth实现的流程
- 微信:跟标准OAuth实现有区别,重点在不同点的细节上
![]()

京公网安备 11010502036488号