OAuth认证

https://www.wuhuachuan.com/visitor/learning/article/getArticleDetail?id=e70818e5-f5f1-4640-b928-f908bece0463&utm_source=tuicool&utm_medium=referral

前言

主要想总结下工作中使用的 Kong 集成 OAuth 这项技术,所以转载这篇文章先介绍 OAuth 的一些概念。如果有时间,还是读一下 OAuth RFC 文档好: 点这里

OAuth 概念

OAuth 是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表), 而不需要将用户名和密码提供给第三方应用。 OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。 每一个令牌授权一个特定的网站在特定的时段内访问特定的资源。 这样,OAuth让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容。

OAuth 运行流程

首先会有几个术语:

  • Resource owner : 资源所有者,本文中称为 “用户”。
  • Authorization server :认证服务器,即服务提供商专门用来处理认证的服务器。
  • Resource server:资源服务器,即用户提供商存放用户生成的资源的服务器。它和认证服务器,可以是同一台服务器,也可以是不同的服务器。

总的来说, 认证服务器 和 资源服务器 都由 服务提供商 提供。流程如下图:

文字解释:

  • 用户打开客户端以后,客户端要求用户给予授权。
  • 用户同意给予客户端授权。
  • 客户端使用上一步获得的授权,向认证服务器申请令牌。
  • 认证服务器对客户端进行认证后,确认无误后,同意发放令牌。
  • 客户端使用令牌,向资源服务器申请获取资源。
  • 资源服务器确认令牌无误后,同意向客户端开放资源。

上面的 6 个步骤中,重点在于 2 ,即用户怎么给客户端授权,有了这个授权,客户端就可以获取令牌,进而凭借令牌获取资源。

OAuth 授权模式

OAuth2.0 定义了 四种授权模式。分别为:

  • 授权码模式
  • 简化模式
  • 密码模式
  • 客户端模式

授权码 模式

授权码模式是功能最完整,流程最严密的授权模式。它的特定就是通过客户端的后台服务器,与“服务提供商”的认证服务器进行互动。流程如下图:

解释:

首先,用户访问客户端,后者将前者导向认证服务器。如: https://www.example.com/v1/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read

  • www.example.com/v1/oauth/authorize :API 授权的终端。
  • client_id :应用程序的client ID,用于 API 识别应用程序。
  • redirect_uri :获得授权码之后,服务提供商重定向用户代理(比如浏览器)的地址。
  • response_type : 表明授权类型,默认是 code。即授权码模式。
  • scope: 应用程序可以获得的授权级别,默认值为 read。
  • state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值,用于抵御 CSRF 攻击。

然后,用户选择是否给予授权。如下图:

假如用户给予授权,认证服务器将用户导向客户端事先指定的 “重定向URL”,同时附上一个授权码: https://www.jianshu.com/callback?code=AUTHORIZATION_CODE

客户端收到授权码,附上之前的 “重定向URI” 向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。

https://www.example.com/v1/oauth/token? client_id=CLIENT_ID& client_secret=CLIENT_SECRET& grant_type=authorization_code& code=AUTHORIZATION_CODE& redirect_url=REDIRECT_URL

URI 包括:

  • www.example.com/v1/oauth/authorize :API Token的终端。
  • client_id :即 app key / consumer key ,用于验证应用程序。
  • client_secret:即 app secret / consumer secret 用于验证应用程序。
  • grant_type :刚刚获得的授权码
  • redirect_uri :重定向URI,和第一步一致。

认证服务器核对了授权码 和 重定向 URI 确认无误后,向客户端发送访问令牌和 更新令牌。

{ "access_token":"ACCESS_TOKEN", "token_type":"bearer", "expires_in":2592000, "refresh_token":"REFRESH_TOKEN", "scope:read" }

包括了:

  • access_token:访问令牌
  • token_type :令牌类型
  • expires_in :过期时间,单位为秒
  • refresh_token: 更新令牌,用来获取下一次的访问令牌。
  • scope:权限范围。

Ps:这里可能会有一个疑惑,为什么要发送两次请求得到 token,为什么要有 code?

是这样子的:

  1. 浏览器的 redirect uri 是一个不安全信道,此方式不适合于传递敏感数据(如 access token)。 因为 uri 可能通过 HTTP referrer 被传递给其它恶意站点,也可能存在于浏览器 cacher 或 log 文件中,这就给攻击者盗取 access token 带来了很多机会。 另外,此协议也不应该假设 RO 用户代理的行为是可信赖的,因为 RO 的浏览器可能早已被攻击者植入了跨站脚本用来监听 access token。 因此,access token 通过 RO 的用户代理传递给 Client,会显著扩大 access token 被泄露的风险。 但 authorization code 可以通过 redirect uri 方式来传递,是因为 authorization code 并不像 access token 一样敏感。 即使 authorization code 被泄露,攻击者也无法直接拿到 access token,因为拿 authorization code 去交换 access token 是需要验证 Client 的真实身份。 也就是说,除了 Client 之外,其他人拿 authorization code 是没有用的。 此外,access token 应该只颁发给 Client 使用,其他任何主体(包括 RO)都不应该获取 access token。 协议的设计应能保证 Client 是唯一有能力获取 access token 的主体。 引入 authorization code 之后,便可以保证 Client 是 access token 的唯一持有人。 当然,Client 也是唯一的有义务需要保护 access_token 不被泄露。
  2. 引入 authorization code 还会带来如下的好处。 由于协议需要验证 Client 的身份,如果不引入 authorization code,这个 Client 的身份认证只能通过第1步的 redirect uri 来传递。 同样由于 redirect uri 是一个不安全信道,这就额外要求 Client 必须使用数字签名技术来进行身份认证,而不能用简单的密码或口令认证方式。 引入 authorization_code 之后,AS 可以直接对 Client 进行身份认证(见步骤4和5),而且可以支持任意的 Client 认证方式(比如,简单地直接将 Client 端密钥发送给 AS)。

简化模式

简化模式不经过第三方应用程序的服务器,直接在浏览器中向认证服务器 申请令牌,跳过了“授权码” 这个步骤,所以步骤都在浏览器中完成,令牌对访问者是可见的,而且客户端不需要认证。这种模式一般是用于客户端应用程序,比如手机应用,桌面客户端应用程序和运行于浏览器上的Web应用程序。授权令牌会交给用户代理,再由用户代理交给应用程序。如下图:

首先,还是用户访问客户端,客户端将用户导向认证服务器。 https://www.example.com/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read

然后,用户选择是否给予客户端授权:

假如用户给予授权,认证服务器将用户导向客户端事先指定的 “重定向URI” ,并且在 URI 的 hash 部分包含了访问令牌: https://www.example.com/callback#token=ACCESS_TOKEN

then 浏览器向资源服务器发出请求,其中不包括上一步收到的 hash 值。

then 资源服务器返回一个网页,其中包含的代码可以获取Hash 值中的令牌。

then 浏览器执行上一步获得的脚本,提出令牌。

finally 浏览器将令牌发送给客户端。

密码模式

即用户向客户端提供用户名密码。客户端使用这些信息,向 “服务商提供商” 索要授权。在这种模式下,客户端不得存储密码。 这通常用在用户对客户端高度可信的情况下。 一般,认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。如下图:

  1. 用户向客户端提供用户名,密码。
  2. 客户端用用户名,密码发送给认证服务器,向后者申请令牌。
  3. 认证服务器确认无误后,向客户端提供访问令牌。

客户端模式

客户端使用自己的名义,而不是用户的名义,向“服务提供商” 进行认证。严格来说,客户端模式并不属于OAuth 框架所需要解决的问题。在这种模式下,用户直接向客户端注册,客户端以自己的名义要求“服务提供商”提供服务,其实并不存在授权。如下图:

  1. 客户端向认证服务器进行身份认证,并且要求一个访问令牌。
  2. 认证服务器认证无误后,向客户端提供访问令牌。

对于这种方式,用在 访问一些和用户无关的Open Api,比如一些首页数据,这些数据和用户无关,但是又不想任何人都可以调用这个WebApi,那么就可以采用这种模式。

参考

写在最后

  1. 写出来,说出来才知道对不对,知道不对才能改正,改正了才能成长。
  2. 在技术方面,希望大家眼里都容不得沙子。如果有不对的地方或者需要改进的地方希望可以指出,万分感谢。
时间: 2024-10-10 17:13:08

OAuth认证的相关文章

拿nodejs快速搭建简单Oauth认证和restful API server攻略

拿nodejs快速搭建简单Oauth认证和restful API server攻略:http://blog.csdn.net/zhaoweitco/article/details/21708955 最近一直在鼓捣这个东西,拿出来分享下一下经验吧,其实很简单,一点也不难. 首先需求是这样,给自己的网站要增加API服务,API分为两种,公共的和私有授权的,授权的使用Oauth方法认证身份,API格式均为JOSN和JSONP. 嗯,别的语言我也没怎么学过,首先是找合适的框架进行实现吧.本身网站使用的e

Oauth认证的时候报错:timestamp_refused

今天服务器大规模报错,大部分用户无法登陆,小部分可以登陆,很是奇怪. 查看log,调试代码,发现问题是在oauth认证的时候出了问题,报 timestamp_refused. google了下,问了高手,问题定位在服务器的时间可能有问题 执行date,发现比其他服务器快了5分钟 [[email protected] ~]# date Mon May 19 10:05:48 UTC 2014 同步下时间就解决问题了. [[email protected] ~]# ntpdate time.wind

简单的新浪微博OAuth认证实现

System.setProperty("weibo4j.oauth.consumerKey", Weibo.CONSUMER_KEY); System.setProperty("weibo4j.oauth.consumerSecret", Weibo.CONSUMER_SECRET); Weibo weibo = new Weibo(); // set callback url, desktop app please set to null // http://ca

Android腾讯微博之1.0 Oauth认证

(1)什么是Oauth? Oauth是一个开放的认证协议,让你可以在Web或桌面程序中使用简单而标准的,安全的API认证. 同时,任何第三方都可以使用Oauth认证服务,任何服务提供商都可以实现自身的Oauth认证服务,因而Oauth是开放的. 业界提供了Oauth的多种实现如PHP.JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间,因而Oauth是简易的. 互联网很多服务如Open API,很多大公司如Google,Yahoo,Microsoft等都提供了Oau

基于Thinkphp3.2的qq第三方oauth认证登录扩展类

基于Thinkphp3.2的qq第三方oauth认证登录扩展类,由于腾讯oauth sdk写的太多,不能与thinkphp和好的结合,最终想法讲腾讯oauth sdk写成tp的扩展类先看代码,将代码保存在/library/org/util/Qqconnect.class.php文件中在__construct方法中你可以直接写你的app_id.app_key和回调地址也可以根据自己的喜好,改一下代码传参或者写到配置文件.调用方法:1. 在qq的登录按钮的方法中调用getAuthCode方法例如:$

简单分析第三方登录之oauth认证

关键词:oauth.第三方登录 1.是什么? oauth认证就是一种授权认证机制. 简单分析:用户告诉系统,同意授权第三方应用(eg:本地服务器)进入系统(eg:qq/微信),获取这些数据,系统从而产生一个短期的进入令牌(token),用来代替密码,供第三方应用使用,供第三方应用获取系统数据的一种授权认证机制. 2.为什么? 使用这个认证机制可以方便某些用户省去手动注册账号的麻烦,可以直接利用用户已有的信息来自动帮助用户进行注册,为用户带来便利. 3.怎么做? (1)基本流程: 请求用户授权:用

【pac4j】OAuth 认证机制 入门篇

1,pac4j是什么? pac4j是一个支持多种支持多种协议的身份认证的Java客户端. 2,pac4j的12种客户端认证机制:目前我只有用过第一和第八种. OAuth (1.0 & 2.0): Facebook, Twitter, Google, Yahoo, LinkedIn, Github... using the pac4j-oauth module CAS (1.0, 2.0, SAML, logout & proxy) + REST API support using the

新浪微博oauth认证实现APP第三方登陆

最近在做一个图片分享的APP,为增加用户入口,便于注册,先采用新浪微博作为第三方的入口. 我采用的注册流程如下: 微博的开发者管理平台登录注册过程在这里就不提了,各位看官请自行百度. 介绍WebView的方式进行认证注册 考虑到日后可能添加其他第三方入口,在登陆页面添加如下内容: 1 btnWeibo.setOnClickListener(new View.OnClickListener() { 2 3 @Override 4 public void onClick(View v) { 5 In

照抄播客,纯属无聊,OAuth认证流程

简化版本 这个简化版本是:用户(Resource Owner)访问资源(Resource). 具体版本 1.用户通过浏览器打开客户端后,客户端要求给予授权. 客户端可以直接将授权请求发送给用户,或者发送给一个中间媒介,比如认证服务器. 2.用户同意给予客户端授权,客户端收到用户的授权 授权模式取决于客户端使用的模式,以及认证服务器所支持的模式. 3.客户端提供身份信息,然后想认证服务器发送请求,i申请访问令牌.