启明办公

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 135|回复: 11

OAuth2.0 详解

[复制链接]

1

主题

4

帖子

3

积分

新手上路

Rank: 1

积分
3
发表于 2022-9-21 05:56:44 | 显示全部楼层 |阅读模式
OAuth

在学习OAuth时,会有很多疑问OAuth到底是什么,本文介绍OAuth工作机制.
什么是OAuth?

OAuth 不是一个API或者服务,而是一个验证授权(Authorization)的开放标准,所有人都有基于这个标准实现自己的OAuth。
更具体来说,OAuth是一个标准,app可以用来实现secure delegated access.  OAuth基于HTTPS,以及APIs,Service应用使用access token来进行身份验证。
OAuth主要有OAuth 1.0a和OAuth 2.0两个版本,并且二者完全不同,且不兼容。OAuth2.0 是目前广泛使用的版本,我们多数谈论OAuth时,为OAuth2.0。
为什么要有OAuth?

在OAuth之前,HTTP Basic Authentication, 即用户输入用户名,密码的形式进行验证, 这种形式是不安全的。OAuth的出现就是为了解决访问资源的安全性以及灵活性。OAuth使得第三方应用对资源的访问更加安全。
OAuth 中心组件

OAuth 主要下面中心组件构成 (Central Components), 接下来会依次介绍如下这些组件。

  • Scopes and Consent
  • Actors
  • Clients
  • Tokens
  • Authorization Server
  • Flows
OAuth Scopes

Scopes即Authorizaion时的一些请求权限,即与access token绑定在一起的一组权限。OAuth Scopes将授权策略(Authorization policy decision)与授权执行分离开来。并会很明确的表示OAuth Scopes将会获得的权限范围。
OAuth Actors

OAuth的流程中,主要有如下四个角色。其关系如下图所示:

  • Resource Owner: 用户拥有资源服务器上面的数据。例如:我是一名Facebook的用户,我拥有我的Facebook 个人简介的信息。
  • Resource Server: 存储用户信息的API Service
  • Client: 想要访问用户的客户端
  • Authorization Server: OAuth的主要引擎,授权服务器,获取token。



OAuth Tokens


  • Access token:  即客户端用来请求Resource Server(API). Access tokens通常是short-lived短暂的。access token是short-lived, 因此没有必要对它做revoke, 只需要等待access token过期即可。
  • Refresh token: 当access token过期之后refresh token可以用来获取新的access token。refresh token是long-lived。refresh token可以被revoke。
Token从Authorization server上的不同的endpoint获取。主要两个endpoint为authorize endpoint和token endpoint.  authorize endpoint主要用来获得来自用户的许可和授权(consent and authorization),并将用户的授权信息传递给token endpoint。token endpoint对用户的授权信息,处理之后返回access token和refresh token。 当access token过期之后,可以使用refresh token去请求token endpoint获取新的token。(开发者在开发endpoint时,需要维护token的状态,refresh token rotate)



OAuth有两个流程,1.获取Authorization,2. 获取Token。这两个流程发送在不同的channel,Authorization发生在Front Channel(发生在用户浏览器)而Token发生在Back Channel。

  • Front Channel: 客户端通过浏览器发送Authorization请求,由浏览器重定向到Authorization Server上的Authorization Endpoint,由Authorization Server返回对话框,并询问“是否允许这个应用获取如下权限”。Authorization通过结束后通过浏览器重定向到回调URL(Callback URL)。
  • Back Channel: 获取Token之后,token应有由客户端应用程序使用,并与资源服务器(Resource Service)进行交互。



下面就以实际的OAuth authorization code模式结合HTTP请求来说明Front Channel和Back Channel。
Front channel




Request:
GET https://accounts.google.com/o/oauth2/auth?scope=gmail.insert gmail.send
&redirect_uri=https://app.example.com/oauth2/callback
&response_type=code&client_id=812741506391
&state=af0ifjsldkjGET请求,指定了redirect_uri, 完成authorization之后,需要重定向到哪里。 response_type表明是用哪种OAuth flow进行验证。State为安全标志位,类似于XRSF,更多XRSF可以了解Cross-Site-Request-Forgery (跨站请求伪造)。
Response:
HTTP/1.1 302 Found
Location: https://app.example.com/oauth2/callback?
code=MsCeLvIaQm6bTrgtp7&state=af0ifjsldkj返回的code即表明,已经获得授权authorization grant. state用来保证不是伪造的请求,和request传入的保持一致。
Back channel




Request:
POST /oauth2/v3/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=MsCeLvIaQm6bTrgtp7&client_id=812741506391&client_secret={client_secret}&redirect_uri=https://app.example.com/oauth2/callback&grant_type=authorization_code请求的参数,code即为上一步front channel所返回的code。
Response:
{
  "access_token": "2YotnFZFEjr1zCsicMWpAA",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA"
}当获取到access token之后,就可以在Authorization header中使用token,进行对资源服务器的请求访问
curl -H "Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA" \
  https://www.googleapis.com/gmail/v1/users/1444587525/messagesOAuth Flows


  • implicit flow: 也称之为 2 Legged OAuth 所有OAuth的过程都在浏览器中完成,且access token通过authorization request (front channel only) 直接返回。不支持refresh token。安全性不高。
  • Authorization code: 也称之为 3 Legged OAuth。使用front channel和back channel。front channel负责authorization code grant。back channel负责将authorization code换成(exchange)access token以及refresh token。
  • Client Credential flow: 对于server-to-server的场景。通常使用这种模式。在这种模式下要保证client secret不会被泄露。
  • Resource Owner Password Flow:类似于直接用户名,密码的模式,不推荐使用。
下图即为Authorization code模式下的主要流程图



安全性建议


  • 使用CSRF token。state参数保证整个流程的完整性
  • 重定向URL(redirect URIs)要在白名单内
  • 通过client ID将authorization grant和token request确保在同一个client上发生
  • 对于保密的client(confidential client),确保client secret不被泄露。不要将secret随代码一起发布
OpenID Connect

OpenID Connect 是在OAuth2.0 协议基础上增加了身份验证层 (identity layer)。OAuth 2.0 定义了通过access token去获取请求资源的机制,但是没有定义提供用户身份信息的标准方法。OpenID Connect作为OAuth2.0的扩展,实现了Authentication的流程。OpenID Connect根据用户的 id_token 来验证用户,并获取用户的基本信息。
id_token通常是JWT(Json Web Token),JWT有三部分组成,header,body,signature。header主要用来声明使用的算法,声明claim在body中,并且签名在signature中。OpenID Connection 在OAuth2.0 的基础上额外增加了UserInfo的Endpoint。id_token作为访问UserInfo Endpoint的凭证来获取用户的基本信息(profile,email,phone),并验证用户。



OpenID Connect流程主要涉及如下几个步骤:

  • 发现获取OIDC metadata
  • 执行OAuth流程,获取id_token和access_token。例如:在 Authorization code模式下即为通过code来换取id_token和access_token。
  • 获取JWT签名(signature key)并且可选的动态的注册客户端应用
  • 基于日期签名来本地验证JWT id_token,或者将id_token发给后端backend进行验证
  • 根据id_token通过UserInfo Endpoint获取用户信息,根据access_token获取用户其他资源信息
下图为更详细的流程:



总结

OAuth2.0 不是一个Authentication Protocol, 而是一个Authorization framework,授予应用对API的访问权限(delegate access to APIs)。OAuth设定了对于API访问的scope的权限,以及支持多种授权方式,以及使用场景。OAuth提供了更好的安全性以及便利,简化了软件系统的复杂性。
Reference


  • what-the-heck-is-oauth
  • 理解Oauth2.0
  • stackoverflow oauth2.0-benfits and use case and why?
  • oauth
  • jwt
  • Microsoft id-tokens
  • Microsoft openid-connection
回复

使用道具 举报

0

主题

6

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2022-9-21 05:57:37 | 显示全部楼层
好文,好文!
回复

使用道具 举报

1

主题

6

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 2022-9-21 05:58:00 | 显示全部楼层
请问哪一步做了code和用户的关联啊?
回复

使用道具 举报

0

主题

4

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2022-9-21 05:58:35 | 显示全部楼层
code和用户管理,是用户信息存储方与用户做关联。比如我要使用qq登录某个网站,当跳转到qq登录验证界面时,且验证成功后,这一步code与用户做了关联。

简单来说OAuth是由用户信息存储方,qq登录,微信登录提供相应的接口标准,供第三方网站使用。
回复

使用道具 举报

0

主题

8

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2022-9-21 05:59:00 | 显示全部楼层
好的,多谢[赞]
回复

使用道具 举报

2

主题

8

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2022-9-21 05:59:34 | 显示全部楼层
您好, 请问关于回调参数redrect_uri参数能否改名,也就是换个命名方式,因为我们实际中这个参数被安全设设备拦截了, 正常请求受影响, 所以更改这个回调名能否可行吗? 如能回复,十分感谢
回复

使用道具 举报

0

主题

3

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2022-9-21 05:59:50 | 显示全部楼层
如果你调用的验证服务不在你们控制范围内,那么显然无解。

如果也是你们内部的服务,那么随便修改这个字段,虽然协议是这么定义,但是并不是说一定要教条到必须使用同一个名字。

基本上我看到大多数使用OAuth这套验证流的实现都会根据自己的实际情景进行一定的修改,并不会完全按照协议描述
回复

使用道具 举报

1

主题

5

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 2022-9-21 06:00:08 | 显示全部楼层
要么就都用英语,要么就都用中文。这种中英混合的文章看起来的真的费事儿的很……英文名词为啥不翻译
回复

使用道具 举报

2

主题

4

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2022-9-21 06:00:50 | 显示全部楼层
学习了 在目前看到的几篇文章中讲的最清晰易懂的一篇。 谢谢分享。 请问implicity flow 不安全是因为这种方式只能验证用户, 但无法在获得access_token后验证用到这个token的应用client吗。
另外, 我看到的一些文章 在和Authorisation Code flow 做对比时, 有点用client credential flow 有的用 implicit flow 请问两者的区别是一回事吗 谢谢
回复

使用道具 举报

1

主题

5

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2022-9-21 06:01:15 | 显示全部楼层
前后端分开讲oauth2的过程很清楚,感谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|启明办公

Copyright © 2001-2013 Comsenz Inc.Template by Comsenz Inc.All Rights Reserved.

Powered by Discuz!X3.4

快速回复 返回顶部 返回列表