Web验证方式(3)--OAuth 2.0协议

介绍web

OAuth协议是用来解决第三方应用程序访问Http Service的时候的认证问题。举个例子:某视频网站支持用户经过微信登录,而后获取用户在微信上的图像信息。json

在这个场景里浏览器

  微信充当的就是Http Service角色。安全

  视频网站就是第三方应用服务器

  而视频网站从微信获取用户图像时,微信须要进行认证就是这里的认证问题微信

  用户在微信上登录后,产生的在视频网站中访问用户微信上的图像时所需的认证信息,就是OAuth解决认证问题的方式app

名词定义网站

OAuth协议中定义了以下角色:url

Resource Owner: 资源的全部者,好比此处的微信用户spa

Resource Server: 存储资源的服务器,好比此处的微信服务器

Authorization Server: 负责对用户验证并产生访问Resource Server时所须要的认证信息的服务器。

Client: 向Resource Server请求资源的应用程序。好比此处的视频网站。(网站后台)

User-Agent:用户代理,好比浏览器

整体流程

整体的认证流程以下:

                     图1

A:Client向Resource Owner请求认证信息

B:Resource Owner提供认证信息(好比:用户名密码)

C: 将认证信息提交给Authorization Server进行认证

D:认证经过,Authorization Server返回Access Token

E:Client经过Access Token访问Resource Server中受保护的资源

步骤A,B中能够是发生在Client上,也多是Client将用户导航到Authorization Server上进行。

步骤E中,根据Access Token的类型,Resource Server多是本身验证,也多是调用Authroization Server进行验证。

 

OAuth实际上是建立了一个抽象层(Authorization Server)。

它主要负责两件事情:验证用户,产生统一的用于访问Resource Server验证信息。

验证的用户的方式能够是多种多样(用户名/密码, 手机验证码...),所以这个抽象层将各类验证方式统一为此处的Access Token.这样对Resource Server屏蔽了用户验证的多样性,简化了逻辑。

受权模式

上面流程中最重要的实际上是步骤ABCD,经过收集Resource Owner的认证信息,产生一个Access Token.这个过程称做Resource Owner对Client的受权。OAuth定义了四种受权模式:

受权码模式

简化模式

密码模式

Clent验证模式

 

受权码模式

流程图以下

受权码模式是四种模式中最严谨的一种。Client首先要到Authorization Server上注册,获取到一个Id.(这样只有被容许的Client才能经过OAuth进行验证,增强了安全性)

上面步骤中:

A Client将用户导航到Authorization Server的Authorize endpoint,同时带上clientId(这样Authorization Server能够对Client进行验证),认证结束后的跳转url.

Http请求以下:

GET https://sample.com/authroize?response_type=code&clientId=xxx&redirect_uri=https://www.client.com/oauthcallback.aspx

 

B 用户在Authroization Server的页面上输入本身的验证信息。

C Authorization Server经过导航用户到步骤A中指定的url,并将受权码以query string的形式提供。

Http Response信息以下:

HTTP/1.1 302 Found
Location: https://www.client.com/oauthcallback.aspx?code=xxx

 

D Client获得受权码后,调用Authorization Sever的接口(同时传入受权码和跳转URL,Authroization Server会对二者进行配对验证,以确保安全)

Http请求以下:

POST www.example.com/token 
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=xxx
&redirect_uri=https://www.client.com/oauthcallback.aspx

E Authorization Server返回Access Token给Client,Client存储下来,在后续请求中使用。

Response以下:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" }

 

在这个过程当中,

1. Client没有接触到用户的验证信息(用户名/密码)

2. user-agent没有接触到Access Token。

3. 将受权码与跳转Url配对验证

这些都加强了整个过程的安全性。

简化模式

简化模式,是受权码模式的简化版。流程图以下:

 

这里和受权码模式的区别是:

1. 在步骤A中,直接请求的时token而不是code

GET /authorize?response_type=token&client_id=s6BhdRkqt3&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: www.example.com

 

2. 在步骤C中,Authorization Server直接在跳转url中附带上了access token,跳过了受权码这个环节。可是access token并不是以query string的形式表示,而是以fragment(即url中的hash部分)

Http Response:

HTTP/1.1 302 Found
Location: http://client.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA&token_type=example&expires_in=3600

 

3. 根据http协议的定义,redirect时,fragment不会传到web服务器,所以client要想获得access token,必须在跳转url的response中返回一段js脚原本在浏览器中读到access token而后发送给client.(不太明白,OAuth中为何要将access token放到hash中,而不是query string中)

密码模式

流程图以下:

密码模式中,Resource Owner直接在client的页面上输入认证信息。而后经过client来获取到access token.整个过程当中client不能存储Resource Owner输入的认证信息。可是协议上没办法强制,只能依靠对client的信任了。所以这对Resource Owner来讲是不那么安全的一种方式。

步骤B的请求以下:

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=password&username=johndoe&password=A3ddj3w

步骤C的Response以下:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

 {
       "access_token":"2YotnFZFEjr1zCsicMWpAA",
       "token_type":"example",
       "expires_in":3600,
       "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"
}

Client验证模式

流程图以下:

 

其实这中方式应该不算是OAuth的适用场景里面的。这种模式下是用Client自身在Authorization Server上的认证信息来获取access token.也就是说把client当成一个resource owner,那么就和具体的使用client用户无关了。

扩展模式

采用什么方式获取到access token是经过token请求中的grant_type来肯定的。所以Authorization Server能够经过这个字段来扩展更多的获取access token的方式。

 刷新Access Token

经过上述四种模式得到access token的时候,咱们同时能得到一个refresh token。access token是有有效期的(e.g. 30分钟)。过了有效期后再使用就会报错。这个时候能够适用refresh token去找Authorization Server从新获取access token,这个过程不须要Resource Owner的参与,属于静默执行。

具体请求以下:

 

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA

 

 

 

验证Access Token

access token最后是发送给Resource Server的,因此Resource Server会对access token进行验证。而具体的验证方法取决与token的类型。

1. 若是token是一个不包含特定信息的字符串。Resource Server只能将这个token交给Authorization Server去解析拿到用户信息了。

2. 若是token是一个包含特定用户信息的字符串(e.g. jwt)。Resource Server则能够自行解析token拿到用户信息。

 

Authorization Server与Resource Server

Authorization Server和Resource Server能够是在同一台服务器上。也能够是在不一样的服务器上。

1. 在同一服务器上

这种状况下第三方应用和HTTP Service实际上是同一个应用,也就是任意的http应用自身的用户验证均可以应用OAuth协议。这种状况下,Authorization Server是应用的一个模块。

2. 在不一样服务器上

这种状况的适用场景就比较多了。Authorization Server能够对应多个Resource Server,从而全部的Resource Server均可以把Authorization server 做为用户认证信息提供者。SSO,OPEN ID均可以用这种场景。

参考:RFC6749

CS模式应用采用OAuth

前面讨论的都是BS的Web应用。CS模式的应用(通讯协议为Http)也是能够采用OAuth协议的。

以常见的app开发为例:

app的后台服务其实就是resource server,咱们能够把authorization server单独部署或者和resource server一块儿部署,或者是后台服务的一个模块。可是因为app是本身开发的产品,属于可信任的client。所以能够采用密码模式。其余模式涉及url跳转,独立的验证页面等有点太复杂了。

不过若是app的后台要做为一个开放平台,供别的app调用,就须要支持其余模式了。由于跳转是发生在浏览器里的,所以这种状况下app的实现也会复杂点。

相关文章
相关标签/搜索