Oauth2基本介绍

OAuth2

一、什么是OAuth2

OAuth 2.0是目前最流行的授权机制,用来授权第三方应用,获取用户数据。

OAuth(开放授权)是一个关于授权的开放标准,允许用户授权第三方移动应用访问他们存储在另外的服务提供者上的信息(比如照片、视频、用户信息等),而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容,OAuth2.0是OAuth协议的延续版本,但不向后兼容OAuth 1.0。即完全废止了OAuth1.0。OAuth 2.0协议正式发布为RFC-6749。

OAuth2主要包含以下特点:

1、用于REST/APIs的代理授权 框架(delegated authorization framework)

2、基于令牌Token的授权, 在无需暴露用户密码的情况下,使应用能获取对用 户数据的有限访问权限

3、解耦认证和授权

4、事实上的标准安全框架,支持多种用例场景

  1. 服务器端WebApp
  2. 浏览器单页SPA
  3. 无线/原生App
  4. 服务器对服务器之间 oauth2

在这里插入图片描述

二、OAuth2的原理

在常规情况下应用请求资源服务器, 访问客户数据,在没有OAuth2的情况下,资源服务器区分不出请求过来的应用是恶意用户还是其他用户,数据都会返回。 如下图所示:
在这里插入图片描述

因此为了用户安全访问数据,在访问中间添加了Access Token机制。客户端需要携带Access Token去访问受到保护的资源。
在这里插入图片描述

OAuth2就是让我们使用授权服务器颁发给客户应用Access Token。

扫描二维码关注公众号,回复: 12332782 查看本文章

在这里插入图片描述

最后客户端拿到Access Token去资源服务器进行校验,验证通过之后才返回数据。

OAuth2的整体流程图如下:
在这里插入图片描述

流程图

(A)客户端向资源所有者请求授权。授权请求可以直接对资源所有者(如图所示)进行,或者通过授权服务器作为中介进行间接访问(首选方案)。
(B)资源所有者允许授权,并返回凭证(如code)。
(C)客户端通过授权服务器进行身份验证,并提供授权凭证(如code),请求访问令牌(access token)。
(D)授权服务器对客户端进行身份验证,并验证授权凭证,如果有效,则发出访问令牌。
(E)客户端向资源服务器请求受保护的资源,并通过提供访问令牌来进行身份验证。
(F)资源服务器验证访问令牌,如果正确则返回受保护资源。

简单说就是:客户应用向授权服务器请求Access Token —> 授权服务器向用户征询意见,是否将权限授予客户应用 —> 用户同意 —> 授权服务器生成颁发Access Token给客户应用 —> 客户应用拿着Access Token去请求资源服务器 —> 资源服务器验证客户应用的Access Token —> 验证通过,返回数据

三、OAuth2中的角色和术语

在OAuth2中主要有四个角色,主要如下:

  1. Resource Owner(资源所有者):用户,即资源的拥有人,想要分享某些资 源给第三方应用
  2. Resource Server(资源服务器):放受保护资源,要访问这些资源,需要获得访问令牌
  3. Authorization server(授权(认证)服务器):授权服务器用于发放访问令牌给客户端
  4. Client(客户端(第三方应用)):客户端代表请求资源服务器资源的第三方程序

OAuth2中的其他术语:

  1. Client Credentials(客户凭证):客户的clientId 和密码用于认证客户
  2. Access Token(访问令牌):授权服务器在接收到客户请求后,颁发的访问令牌
  3. Scopes(作用域):客户请求访问令牌时,由资源拥有者额外指定的细分权限(permission)
  4. User Agent(用户代理):用户代理。一般就是指浏览器

OAuth2中的令牌类型:

  1. Authorization Code Token(授权码):仅用于授权码授权类型,用于交换获取访问令牌和刷新令
  2. Refresh Token(刷新令牌):用于去授权服务器获取一个新的访问令牌
  3. Access Token(访问令牌):用于代表一个用户或服务直接去访问受保护的资源
  4. Proof of Possession(PoP) Token(持有证明(pop)令牌):可以校验client是否对Token 有明确的拥有权

通过上面的介绍我们大概总结如下:

OAuth的本质在于如何获取token,如何使用token
OAuth是一种在系统之间的代理授权(delegation authorization)协议
OAuth提供一个宽泛的协议框架,具体安全场景需要定制
OAuth使用代理协议的方式解决密码共享反模式问题

四、OAuth2的四种授权方式

从运行流程不难看出,要获取access token必须先得到用户授权(authorzation grant),那么如果获取这么用户授权呢?OAuth 2.0定义了四种类型的授权类型

  1. 授权码模式(authorization code)
  2. 简化模式(implicit)
  3. 密码模式(resource owner password credentials)
  4. 客户端模式(client credentials)

1、授权码模式(authorization code)

授权码模式是功能最完整、使用最广泛、流程最严密的授权模式。

授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。

在这里插入图片描述

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

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

在URI中response_type参数表示要求返回授权码(code),client_id参数让授权服务器知道是谁在请求,redirect_uri参数是授权服务器接受或拒绝请求后的跳转网址,scope参数表示要求的授权范围(这里是只读)。

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

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

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

第四步:客户端收到授权码,附上早先的重定向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

注意:用户密匙和密码可以在headers里添加认证,Authorization。

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

第五步:授权服务器对客户端进行身份验证,验证授权代码,并确保所收到的重定向URI与用于在步骤©中对客户端重定向的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"
}

这里的参数主要是:

access_token:表示访问令牌。必选项。
token_type:表示令牌类型。该值大小写不敏感,必选项,可以是bearer类型或mac类型。
expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。
refresh_token:表示更新令牌。可选项,用来获取下一次的访问令牌。
scope:表示权限范围。可选项,如果与客户端申请的范围一致,此项可省略。

最后我们拿到access_token去访问受保护的资源即可,如下:

http://localhost:8080/api/userinfo?access_token=f4345f3a-34a3-4887-bc02-e95150c54bf4

2、简化模式(implicit)

简化模式(implicit grant type)不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了"授权码"这个步骤,因此得名。所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。
在这里插入图片描述

第一步:用户访问客户端,客户端将用户导向授权服务器,通过用户代理(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,scope权限,state用于认证标记,传过去什么回调时传回来什么。

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

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

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

同理,我们拿到access_token就可以访问受保护的资源了。

http://localhost:8080/api/userinfo?access_token=0406040a-779e-4b5e-adf1-bf2f02031e83

3、密码模式(resource owner password credentials)

密码模式中,用户向客户端提供自己的用户名和密码。客户端使用这些信息,向"服务商提供商"索要授权。

在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。这通常用在用户对客户端高度信任的情况下,比如客户端是操作系统的一部分,或者由一个著名公司出品。而认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。

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

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

注意:用户密匙和密码(client_id和client_secret)可以在headers里添加认证,Authorization。

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

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

同理,拿到access_token即可访问我们需要访问的资源。

4、客户端模式(client credentials)

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

client

第一步:客户端直接向授权服务器发起认证请求,URI如下:

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

注意:用户密匙和密码(client_id和client_secret)也可以在headers里添加认证,Authorization。

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

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

最后我们拿到access_token即可访问相关资源。

猜你喜欢

转载自blog.csdn.net/weixin_42272869/article/details/112260123