Spring Security
Oauth2认证
简介
第三方认证技术方案最主要是解决认证协议的通用标准问题,因为要实现跨系统认证,各系统之间要遵循一定的接口协议。
OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。同时,任何第三方都可以使用OAUTH认证服务,任何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP、JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间,因而OUTH是简易的。互联网很多服务如OpenAPI,很多大公司Google,Yahoo,Microsoft等都提供了OAUTH认证服务,这些都足以说明OAUTH标准逐渐成为开放资源授权的标准。
Oauth协议目前发展到2.0版本,1.0版本过于复杂,2.0版本已得到广泛应用。
参考:https://baike.baidu.com/item/oAuth/7153134?fr=aladdin
Oauth协议:https://tools.ietf.org/html/rfc6749
Oauth2.0协议认证流程:
+--------+ +---------------+
| |--(A)- Authorization Request ->| Resource |
| | | Owner |
| |<-(B)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(C)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(D)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(E)----- Access Token ------>| Resource |
| | | Server |
| |<-(F)--- Protected Resource ---| |
+--------+ +---------------+
+--------+ +---------------+
| |---A.请求授权.Authorization Request---> | |
| | | 资源拥有者 |
| |<--B授权许可.Authorization Grant -------| |
| | +---------------+
| |
| | +---------------+
| |---C授权许可.Authorization Grant --->| |
| 客户端 | | 授权服务器 |
| |<--D.访问令牌.Access Token ----------| |
| | +---------------+
| |
| | +---------------+
| |---E.访问令牌 Access Token --------->| |
| | | 资源服务器 |
| |<--F.s受保护资源Protected Resource---| |
+--------+ +---------------+
角色
客户端:
本身不存储资源,需要通过资源拥有者的授权去请求资源服务器的资源,比如:Android客户端、Web客户端(浏览脂端)、微信客户端等。
资源拥有者:
通常为用户,也可以是应用程序,即该资源的拥有者。
授权服务器(也称认证服务器):
用来对资源拥有的身份进行认证、对访问资源进行授权。客户端要想访问资源需要通过认证服务器由资源拥有者授权后方可访问。
资源服务器:
存储资源的服务器,比如,网站用户管理服务器存储了网站用户信息,网站相册服务器存储了用户的相册信息,微信的资源服务存储了微信的用户信息等。客户端最终访问资源服务器获取资源信息。
常用术语
- 客户凭证(client Credentials):客户端的clientID和密码,用于认证客户
- 令牌(tokens):授权服务器在接收到客户端请求后,颁发的访问令牌
- 作用域(scopes):客户请求访问令牌时,由资源拥有者额外指定的细分权限(permission)
令牌类型
- 授权码:仅用于授权码授权类型,用于交换获取访问令牌和刷新令牌
- 访问令牌:用于代表一个用户或服务直接去访问受保护的资源
- 刷新令牌:用于去给授权服务器获取一个刷新的访问令牌
- BearerToken:不管谁拿到Token都可以访问资源
- Proof of Possession(PoP) Token:可以校验client是否对Token有明确的拥有权
特点
优点:
- 更安全,客户端不接触用户密码,服务器端更易集中保护
- 广泛传插并被持续采用
- 短寿命和封装的token
- 资源服务器和授权服务器解耦
- 集中式授权,简化客户端
- HTTPJSON友好,易于请求和传递token
- 考虑多种客户端果构场景
- 客户可以具有不同的信任级别
缺点:
- 协议框架太宽泛,造成各种实现的兼容性和互操作性差
- 不是一个认证协议,本身并不能告诉你任何用户信息。
授权模式
授权码模式
Authorization Code Grant:
用于获取访问令牌和刷新令牌,并且已针对机密客户端进行了优化。由于这是基于重定向的流程,因此客户端必须能够
与资源所有者的用户代理(通常是Web 浏览器)进行交互,并且能够(通过重定向)接收来自授权服务器的传入请求。
+----------+
| Resource |
| Owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI ---->| |
| User- | | Authorization |
| Agent -+----(B)-- User authenticates --->| Server |
| | | |
| -+----(C)-- Authorization Code ---<| |
+-|----|---+ +---------------+
| | ^ v
(A) (C) | |
| | | |
^ v | |
+---------+ | |
| |>---(D)-- Authorization Code ---------' |
| Client | & Redirection URI |
| | |
| |<---(E)----- Access Token -------------------'
+---------+ (w/ Optional Refresh Token)
(A)客户端通过将资源所有者的 用户代理定向到授权端点来启动该流程。客户端包括其客户端标识符,请求的范围,本地状态和 重定向URI, 一旦授予(或拒绝)访问权限,授权服务器便会将用户代理发送回该重定向URI。
(B)授权服务器(通过 用户代理)对资源所有者进行身份验证,并确定资源所有者是授予还是拒绝客户端的访问请求。
(C)假设资源所有者授予访问权限,授权 服务器使用先前提供的重定向URI(在请求中或在客户端注册期间)将用户代理重定向回客户端。重定向URI包括授权码和客户端之前提供的任何本地状态。
(D)客户端 通过包括上一步中收到的授权代码,从授权服务器的令牌端点请求访问令牌。发出请求时,客户端向授权服务器进行身份验证。客户端包括用于获得授权的重定向URI验证码。
(E)授权服务器对客户端进行身份验证,验证授权代码,并确保在步骤(C)中接收到的重定向URI与用于重定向客户端的URI匹配。如果有效,授权服务器将以访问令牌和(可选)刷新令牌进行响应。
隐式授权模式
Implicit Grant:
用于获取访问令牌(它不支持刷新令牌的发行),并且已针对公共对象进行了优化。
已知操作特定重定向URI的客户端。这些客户端通常是在浏览器中使用脚本语言(例如JavaScript)实现的。
由于这是基于重定向的流程,因此客户端必须能够与资源所有者的用户代理(通常是Web浏览器)进行交互,
并且能够(通过重定向)接收来自授权服务器的传入请求。
与授权代码授予类型不同,在授权类型授予类型中,客户端分别提出授权请求和访问令牌请求,而客户端则接
收访问令牌作为授权请求的结果。
隐式授予类型不包括客户端身份验证,而是取决于资源所有者的存在和重定向URI的注册。由于访问令牌已编码到
重定向URI中,因此它可能会暴露给资源所有者和驻留在同一设备上的其他应用程序。
+----------+
| Resource |
| Owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI --->| |
| User- | | Authorization |
| Agent -|----(B)-- User authenticates -->| Server |
| | | |
| |<---(C)--- Redirection URI ----<| |
| | with Access Token +---------------+
| | in Fragment
| | +---------------+
| |----(D)--- Redirection URI ---->| Web-Hosted |
| | without Fragment | Client |
| | | Resource |
| (F) |<---(E)------- Script ---------<| |
| | +---------------+
+-|--------+
| |
(A) (G) Access Token
| |
^ v
+---------+
| |
| Client |
| |
+---------+
(A)客户端通过将资源所有者的用户代理定向到授权端点来启动该流程。客户端包括
其客户端标识符,请求的范围,本地状态和 重定向URI,一旦授予(或拒绝)
访问权限,授权服务器便会将用户代理发送回该重定向URI。
(B)授权服务器(通过用户代理)对资源所有者进行身份验证,并确定资源所有者是
授予还是拒绝客户端的访问请求。
(C)假设资源所有者授予访问权限,授权服务器使用前面提供的重定向URI将用户代
理重定向回客户端。重定向URI在URI片段中包含访问令牌。
(D)用户代理通过对Web托管的客户端资源(不包括[ RFC2616 ]的片段)进行请求,
从而遵循重定向指令。用户代理在本地保留片段信息。
(E)由网络托管的客户端资源返回能够访问以下内容的网页(通常是带有嵌入式脚本的
HTML文档)完整的重定向URI,包括由用户代理保留的片段,并提取片段中包含的访问令牌
(和其他参数)。
(F)用户代理在本地执行由Web托管的客户端资源提供的脚本,该脚本提取访问令牌。
(G)用户代理将访问令牌传递给客户端。
密码模式
Resource Owner Password Credentials Grant:
适合在其中资源所有者具有与信任关系的情况下的客户端,例如设备的操作系统或一个高特权
应用程序。授权服务器在启用此授予类型时应格外小心,并且仅在其他流程不可行时才允许它。
此授予类型适用于能够获得资源所有者的凭据(用户名和密码,通常使用交互形式)的客户端。
通过将存储的凭据转换为访问令牌,它还可用于使用直接身份验证方案(例如HTTP基本或摘要身份验证)
将现有客户端迁移到OAuth。
+----------+
| Resource |
| Owner |
| |
+----------+
v
| Resource Owner
(A) Password Credentials
|
v
+---------+ +---------------+
| |>--(B)---- Resource Owner ------->| |
| | Password Credentials | Authorization |
| Client | | Server |
| |<--(C)---- Access Token ---------<| |
| | (w/ Optional Refresh Token) | |
+---------+ +---------------+
(A)资源所有者向客户端提供其用户名和密码。
(B)客户端通过包括从资源所有者接收的凭据,从授权服务器的令牌端点请求访问令牌。
发出请求时,客户端向授权服务器进行身份验证。
(C)授权服务器对客户端进行身份验证并验证资源所有者凭据,如果有效,则颁发访问
令牌
客户端模式
Client Credentials Grant:
+---------+ +---------------+
| | | |
| |>--(A)- Client Authentication --->| Authorization |
| Client | | Server |
| |<--(B)---- Access Token ---------<| |
| | | |
+---------+ +---------------+
(A)客户端通过授权服务器进行身份验证,并从令牌端点请求访问令牌。
(B)授权服务器对客户端进行身份验证,如果有效,则颁发访问令牌。
刷新令牌
刷新令牌是用于获取访问令牌的凭据。
授权服务器将刷新令牌发布给客户端,并在当前访问令牌变为无效或过期时用于获取新的访问令牌,
或者用于获取范围相同或范围更窄的其他访问令牌。
+--------+ +---------------+
| |--(A)------- Authorization Grant --------->| |
| | | |
| |<-(B)----------- Access Token -------------| |
| | & Refresh Token | |
| | | |
| | +----------+ | |
| |--(C)---- Access Token ---->| | | |
| | | | | |
| |<-(D)- Protected Resource --| Resource | | Authorization |
| Client | | Server | | Server |
| |--(E)---- Access Token ---->| | | |
| | | | | |
| |<-(F)- Invalid Token Error -| | | |
| | +----------+ | |
| | | |
| |--(G)----------- Refresh Token ----------->| |
| | | |
| |<-(H)----------- Access Token -------------| |
+--------+ & Optional Refresh Token +---------------+
刷新过期的访问令牌
(A)客户端通过与授权服务器进行身份验证并提供授权授权来请求访问令牌。
(B)授权服务器对客户端进行身份验证并验证授权授权,如果有效,则颁发访问令牌
和刷新令牌。
(C)客户端通过提供访问令牌向资源服务器发出受保护的资源请求。
(D)资源服务器验证访问令牌,如果有效,则服务该请求。
(E)重复步骤(C)和(D),直到访问令牌过期。如果客户端知道访问令牌已过期,
则跳至步骤(G);否则,它将发出另一个受保护的资源请求。
(F)由于访问令牌无效,因此资源服务器返回无效令牌错误。Hardt标准曲目[第11页]
(G)客户端通过与授权服务器进行身份验证并提供刷新令牌来请求新的访问令牌。该
客户端身份验证的要求是基于客户端类型和授权服务器策略。
(H)授权服务器对客户端进行身份验证并验证刷新令牌,如果有效,则颁发新的访问令牌(以及
可选的新的刷新令牌)。
授权服务器
- Authorize Endpoint:授权端点,进行授权
- Token Endpoint:令牌端点,经过授权拿到对应的Token
- **Introspection Endpoint:**校验端点,校验Token的合法性
- Revocation Endpoint:撤销端点,撤销授权
Spring Security Oauth2架构流程图
—————————————————–流程(ZD)—————————————————————
- 1.用户访问,此时没有Token,Oauth2RestTemplate会报错,这个报错信息会被Oauth2ClientContextFilter捕获并重定向到认证服务器
- 2.认证服务器通过Authorization Endpoint进行授权,并通过AuthorizationServerTokenServices生成授权码并返回给客户端
- 3.客户端拿到授权码去认证服务器通过Token Endpoint调用AuthorizationServerTokenServices生成Token并返回给客户端
- 4.客户端拿到Token去资源服务器访问资源,一般会通过Oauth2AuthenticationManager调用ResourceServer TokenServices进行校验。校验通过可以获取资源。
- Post link: http://sovzn.github.io/2021/05/10/SpringSecurity-03/
- Copyright Notice: All articles in this blog are licensed under unless otherwise stated.
若没有本文 Issue,您可以使用 Comment 模版新建。
GitHub Issues