OAuth2介绍与使用

1. 什么是OAuth2

OAuth(Open Authorization:开放授权)是一个开放标准,允许用户授权第三方移动应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容,OAuth2.0是OAuth协议的延续版本,但不向后兼容OAuth 1.0即完全废止了OAuth1.0。

2. OAuth2运行流程

OAuth2介绍与使用_第1张图片

(A)用户打开客户端以后,客户端要求用户给予授权。

(B)用户同意给予客户端授权。

(C)客户端使用上一步获得的授权,向认证服务器申请令牌。

(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。

(E)客户端使用令牌,向资源服务器申请获取资源。

(F)资源服务器确认令牌无误,同意向客户端开放资源。

3. 四种授权模式

授权码模式(authorization code):

适用于常见需要授权应用;授权码模式是功能最完整、使用最广泛、流程最严密的授权模式。授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。

OAuth2介绍与使用_第2张图片

 

(1)用户访问客户端,客户端将用户导向授权服务器,通过用户代理(User-Agent)发送包括它的客户端标识符、请求的范围、本地状态和一个重定向URI,授权服务器在授予(或拒绝)访问权后将其发送给用户代理。URI如下:

http://localhost:8080/oauth/authorize?client_id=clientapp&redirect_uri=http://localhost:9001/callback&response_type=code&scope=read_userinfo

其中response_type:表示要求返回授权码(code),client_id:请求客户端标识,redirect_uri:授权服务器处理后跳转地址,scope:请求授权范围。

(2)授权服务器对资源所有者进行身份验证(通过用户代理,让用户输入用户名和密码),并确定资源所有者是否授予或拒绝客户端的访问请求。

(3)用户跳转后,假如资源所有者同意授权请求,那么授权服务器将会使用前面提供的或者事先指定的重定向URI(redirection URI),重定向到客户端,并附上一个授权码(code)和一个前面提供的本地状态(state)(如果有的话,则会原值返回)。

http://localhost:9001/callback?code=ghN0hf

(4)客户端收到授权码,附上早先的重定向URI,向授权服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。在发出请求时,授权服务器对客户端进行身份验证。请求参数包含授权代码、用于获得验证的授权代码的重定向URI、标识客户端身份的client id和client secret。

http://localhost:8080/oauth/token?client_id=clientapp&client_secret=123&code=ghN0hF&grant_type=authorization_code&redirect_uri=http://localhost:9001/callback&scope=read_userinfo

注意:用户密匙和密码(client_id和client_secret)可以在headers里添加认证,Authorization。其中client_id参数和client_secret参数用来让授权服务器确认客户端的身份(client_secret参数是保密的,因此只能在后端发请求),grant_type参数的值是authorization_code,表示采用的授权方式是授权码,code参数是上一步拿到的授权码,redirect_uri参数是令牌颁发后的回调网址。

(5)授权服务器对客户端进行身份验证,验证授权代码,并确保所收到的重定向URI与步骤(3)中对客户端重定向的URI相匹配,如果检查通过,授权服务器将发送访问令牌access token和刷新令牌refresh token(可选)。​

然后授权服务器给我们返回授权码,如下:

{
    "access_token": "36cded80-b6f5-43b7-bdfc-594788a24530",
    "token_type": "bearer",
    "expires_in": 43199,
    "refresh_token":"45cdce99-b6f5-8866-bdfc-764745a45780",
    "scope": "read_userinfo"
}

 

简化模式(implicit):

适用于公开的浏览器单页应用;简化模式不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了"授权码"这个步骤,因此得名。所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。

OAuth2介绍与使用_第3张图片

(1)用户访问客户端,客户端将用户导向授权服务器,通过用户代理(User-Agent)发送包括它的客户端标识符、请求的范围、本地状态和一个重定向URI,授权服务器在授予(或拒绝)访问权后将其发送给用户代理。URI如下:

http://localhost:8080/oauth/authorize?client_id=clientapp&redirect_uri=http://localhost:9001/callback&response_type=token&scope=admin&state=abc

这一步直接申请授权token,参数和申请授权码类似,client_id,redirect_uri回调地址,response_type改为直接获取token,state用于认证标记,原样传回。

(2)授权服务器对资源所有者进行身份验证(通过用户代理,让用户输入用户名和密码),并确定资源所有者是否授予或拒绝客户端的访问请求。

(3)用户跳转后,假如资源所有者同意授权请求,那么授权服务器将会使用前面提供的或者事先指定的重定向URI(redirection URI),重定向到客户端,并附上访问令牌等信息。如下:

http://localhost:9001/callback#access_token=0406040a-779e-4b5e-adf1-bf2f02031e83&token_type=bearer&state=abc&expires_in=119

密码模式(resource owner password credentials):

适用于桌面APP等;使用用户名/密码作为授权方式从授权服务器上获取access token,一般不支持refresh token。在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。这通常用在用户对客户端高度信任的情况下,比如客户端是操作系统的一部分,或者由一个著名公司出品。而认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。

OAuth2介绍与使用_第4张图片

(1)用户访问客户端,客户端将用户导向授权服务器,然后提供URI连接包含用户名和密码信息给授权服务器。如下:

http://localhost:8080/oauth/token?client_id=clientapp&client_secret=123&username=anumbrella&password=123456&grant_type=password&scope=admin

(2)授权服务器认证用户名和密码信息正确后,然后返回客户端access_token等信息,如下:

{
    "access_token": "58a02fd5-87f5-44ff-bbdd-d429cf6a2f60",
    "refresh_token":"45cdce99-b6f5-8866-bdfc-dtfsdft55780",
    "token_type": "bearer",
    "expires_in": 43199,
    "scope": "admin"
}

客户端模式(client credentials):

适用于服务器间通信,客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行认证。严格地说,客户端模式并不属于OAuth框架所要解决的问题。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求"服务提供商"提供服务,其实不存在授权问题。

OAuth2介绍与使用_第5张图片

(1)客户端直接向授权服务器发起认证请求,URI如下:

http://localhost:8080/oauth/token?client_id=clientapp&client_secret=123&grant_type=client_credentials&scope=devops

(2)授权服务器通过认证后,直接返回客户端access_token等信息,如下:

{
    "access_token": "776b162a-949e-4dcb-b16b-9985e8171dc0",
    "refresh_token":"46ffdtfa-b6f5-8866-bdfc-dtfsdft55780",
    "token_type": "bearer",
    "expires_in": 43188,
    "scope": "devops"
}

 

你可能感兴趣的:(oauth2)