目录
3. 密码模式(Resource Owner PasswordCredentials)
Spring Security 学习专栏
2. Spring Security 自定义认证管理器和讲解 (二)
7. Spring Security Oauth2学习 (六)
一、 Oauth2 简介
第三方认证技术方案最主要是解决认证协议的通用标准问题,因为要实现跨系统认证,各系统之间要遵循一定的接口协议。OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。同时,任何第三方都可以使用OAUTH认证服务,任何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP、JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间,因而OAUTH是简易的。互联网很多服务如Open API,很多大公司如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认证的例子,网站使用微信认证的过程:
执行流程步骤
1. 用户进入京东网站的登录页面,点击微信的图标以微信账号登录系统,用户是自己在微信里信息的资源拥有者。
2. 点击“微信”出现一个二维码,此时用户扫描二维码,开始给网站授权。
3. 资源拥有者同意给客户端授权
资源拥有者扫描二维码表示资源拥有者同意给客户端授权,微信会对资源拥有者的身份进行验证,验证通过后,微信会询问用户是否给授权网站访问自己的微信数据,用户点击“确认登录”表示同意授权,微信认证服务器会颁发一个授权码,并重定向到网站。
4. 客户端获取到授权码,请求认证服务器申请令牌
此过程用户看不到,客户端应用程序请求认证服务器,请求携带授权码。
5. 认证服务器向客户端响应令牌
认证服务器验证了客户端请求的授权码,如果合法则给客户端颁发令牌,令牌是客户端访问资源的通行证。此交互过程用户看不到,当客户端拿到令牌后,用户在网站看到已经登录成功。
6. 客户端请求资源服务器的资源
客户端携带令牌访问资源服务器的资源。网站携带令牌请求访问微信服务器获取用户的基本信息。
7. 资源服务器返回受保护资源
资源服务器校验令牌的合法性,如果合法则向用户响应资源信息内容。 资源务器和认证服务器可以是一个服务也可以分开的服务,如果是分开的服务资源服务器通常
要请求认证服务器来校验令牌的合法性。
Oauth2.0认证流程如下
引自Oauth2.0协议rfc6749 https://tools.ietf.org/html/rfc6749
三、角色
1. 客户端
本身不存储资源,需要通过资源拥有者的授权去请求资源服务器的资源,比如:Android客户端、Web客户端(浏览器端)、微信客户端等。
2. 资源拥有者
通常为用户,也可以是应用程序,即该资源的拥有者。
3. 授权服务器(也称认证服务器)
用来对资源拥有的身份进行认证、对访问资源进行授权。客户端要想访问资源需要通过认证服务器由资源拥有者授权后方可访问。
4. 资源服务器
存储资源的服务器,比如,网站用户管理服务器存储了网站用户信息,网站相册服务器存储了用户的相册信息,微信的资源服务存储了微信的用户信息等。客户端最终访问资源服务器获取资源信息。
四、常用术语
- 客户凭证(client Credentials) :客户端的clientId和密码用于认证客户
- 令牌(tokens) :授权服务器在接收到客户请求后,颁发的访问令牌
- 作用域(scopes) :客户请求访问令牌时,由资源拥有者额外指定的细分权限(permission)
令牌类型
- 授权码 :仅用于授权码授权类型,用于交换获取访问令牌和刷新令牌
- 访问令牌 :用于代表一个用户或服务直接去访问受保护的资源
- 刷新令牌 :用于去授权服务器获取一个刷新访问令牌
- BearerToken :不管谁拿到Token都可以访问资源,类似现金
- Proof of Possession(PoP) Token :可以校验client是否对Token有明确的拥有权
特点
优点:
- 更安全,客户端不接触用户密码,服务器端更易集中保护
- 广泛传播并被持续采用
- 短寿命和封装的token
- 资源服务器和授权服务器解耦
- 集中式授权,简化客户端
- HTTP/JSON友好,易于请求和传递token
- 考虑多种客户端架构场景
- 客户可以具有不同的信任级别
缺点:
- 协议框架太宽泛,造成各种实现的兼容性和互操作性差
- 不是一个认证协议,本身并不能告诉你任何用户信息。
五、授权模式
1. 授权码模式(Authorization Code)
授权码模式(authorization code)是功能最完整、流程最严密的授权模式。它的特点就是通过客户端的后台服务器,与"服务提供商"的认证服务器进行互动。
执行步骤如下:
(A)用户访问客户端,后者将前者导向认证服务器。
(B)用户选择是否给予客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。
(D)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。
下面是上面这些步骤所需要的参数。
A步骤中,客户端申请认证的URI,包含以下参数:
- response_type:表示授权类型,必选项,此处的值固定为"code"
- client_id:表示客户端的ID,必选项
- redirect_uri:表示重定向URI,可选项
- scope:表示申请的权限范围,可选项
- state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
2. 简化授权模式(Implicit)
它的步骤如下:
(A)客户端将用户导向认证服务器。
(B)用户决定是否给于客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端指定的"重定向URI",并在URI的Hash部分包含了访问令牌。
(D)浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值。
(E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。
(F)浏览器执行上一步获得的脚本,提取出令牌。
(G)浏览器将令牌发给客户端。
下面是上面这些步骤所需要的参数。
A步骤中,客户端发出的HTTP请求,包含以下参数:
- response_type:表示授权类型,此处的值固定为"token",必选项。
- client_id:表示客户端的ID,必选项。
- redirect_uri:表示重定向的URI,可选项。
- scope:表示权限范围,可选项。
- state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
3. 密码模式(Resource Owner PasswordCredentials)
它的步骤如下:
(A)用户向客户端提供用户名和密码。
(B)客户端将用户名和密码发给认证服务器,向后者请求令牌。
(C)认证服务器确认无误后,向客户端提供访问令牌。
B步骤中,客户端发出的HTTP请求,包含以下参数:
- grant_type:表示授权类型,此处的值固定为"password",必选项。
- username:表示用户名,必选项。
- password:表示用户的密码,必选项。
- scope:表示权限范围,可选项。
4. 客户端模式(Client Credentials)
它的步骤如下:
(A)客户端向认证服务器进行身份认证,并要求一个访问令牌。
(B)认证服务器确认无误后,向客户端提供访问令牌。
A步骤中,客户端发出的HTTP请求,包含以下参数:
- granttype:表示授权类型,此处的值固定为"clientcredentials",必选项。
- scope:表示权限范围,可选项。
六、Spring Security Oauth2
1. 授权服务器
Authorize Endpoint :授权端点,进行授权
Token Endpoint :令牌端点,经过授权拿到对应的Token
Introspection Endpoint :校验端点,校验Token的合法性
Revocation Endpoint :撤销端点,撤销授权
2. Spring Security Oauth2架构
流程:
- 用户访问,此时没有Token。Oauth2RestTemplate会报错,这个报错信息会被Oauth2ClientContextFilter捕获并重定向到认证服务器
- 认证服务器通过Authorization Endpoint进行授权,并通过AuthorizationServerTokenServices生成授权码并返回给客户端
- 客户端拿到授权码去认证服务器通过Token Endpoint调用AuthorizationServerTokenServices生成Token并返回给客户端
- 客户端拿到Token去资源服务器访问资源,一般会通过Oauth2AuthenticationManager调用ResourceServerTokenServices进行校验。校验通过可以获取资源。
参考文档