OAuth2授权协议

OAuth2是什么?

OAuth2是一个授权协议。OAuth2.0框架能让第三方应用以有限的权限访问HTTP服务,可以通过构建资源拥有者与HTTP服务间的许可交互机制,让第三方应用代表资源拥有者访问服务,或者通过授予权限给第三方应用,让其代表自己访问服务。

我们需要关心如下角色:

  • 资源拥有者:拥有资源权限的一个人;
  • 受保护的资源:资源拥有者有权限访问的组件,大多数情况下是WebApi形式;
  • 客户端:只要软件使用了受保护的API,它就是客户端;

通过以上组件最终达到的效果是:让客户端为资源拥有者访问受保护资源。用户身份认证直接在用户(和用户的浏览器)与授权服务器之间进行,这个过程对客户端应用不可见。这一重要特性避免了用户将自己的凭证透露给客户端应用,对抗这种反模式正是发明OAuth的原因。

OAuth2不能做什么?

  • OAuth没有定义HTTP协议之外的情形;
  • OAuth不是身份认证协议;
  • OAuth没有定义用户对用户的授权机制;
  • OAuth没有定义授权处理机制;
  • OAuth没有定义令牌的格式;
  • OAuth没有定义加密方式;
  • OAuth不是单体协议;

OAuth2重要组件

  • OAuth客户端:是代表资源拥有者访问受保护资源的软件;
  • 受保护资源:能通过HTTP服务器进行访问,在访问时需要OAuth访问令牌。受保护资源需要验证收到的令牌,受保护资源对是否认可令牌拥有最终决定权;
  • 资源拥有者:有权将访问权限授权给客户端的主体。在大多数情况下,资源拥有者是一个人;
  • OAuth认证服务器:是一个HTTP服务,它在OAuth系统中充当中央组件,授权服务器对资源拥有者和客户端进行身份认证,让资源拥有者向客户端授权、为客户端颁发令牌、为受保护的资源校验令牌;

OAuth2授权许可类型:

  • 授权码许可类型: 不同组件之间保持信息隔离,通过这种方式,浏览器接触不到只应由客户端掌握的信息,客户端也无法得知浏览器的状态;
  • 隐式许可类型: 无法持有客户端密钥,没有授权码这一个保密层,而是直接从授权端点返回令牌,客户端向授权服务器端点请求时,使用的方式与授权码流程相同,只不过response_type参数的值为token,而不是code,这样通知授权服务器直接生成令牌,而不是生成一个用于换取令牌的授权码。
  • 客户端凭据许可类型:对于客户端软件来说资源拥有者不可区分,比如后端系统之间需要直接通信,但是它们并不代表某个特定用户。没有用户对客户端授权。该方式没有刷新令牌的返回。
  • 资源拥有者凭据许可类型:客户端通过后端信道使用用户名和密码换取OAuth令牌;
  • 断言许可类型:断言许可类型是由OAuth工作组发布的第一个官方拓展许可类型,在这种许可类型下,客户端会得到一条结构化的且被加密保护的信息,叫做断言,使用断言向授权服务器换取令牌。

OAuth2安全相关:

  • 如何有效防范CSRF攻击:支持授权码许可类型的客户端应生成一个难以猜测state参数,并在首次向授权服务器发送请求时将其一同传递,OAuth规范要求授权服务器将此参数原样返回至重定向客户端URI,客户端要检查state参数的值,如果不一致则客户端需要中止授权流程。
  • 令牌端点无需重定向为什么还需要携带redirect_uri:根据OAuth规范,如果在授权请求中指定了重定向URI,那么令牌端点也必须包含该重定向URI,这可防止攻击者使用被篡改的重定向URI获取受害者的授权码,让并无恶意的客户端将受害用户的资源访问权限关联到攻击者账户。
  • 通过Referrer盗用授权码:基于HTTP Referrer造成的信息泄露,攻击者的最终目的是劫持资源拥有者的授权码。被攻击客户端的需要满足的前提要求:授权码模式+允许子目录的redirect_uri校验策略。
  • 客户端不能多次使用同一个授权码。如果一个客户端使用了已经被用过的授权码,授权服务器必须拒绝该请求,并且应该尽可能地撤回之前通过该授权码颁发的所有令牌。
  • 保证授权码只会颁发给经过身份认证的客户端;如果客户端不是保密客户端,则要确保授权码只会颁发给请求中client_id对应的客户端。如果不做这项检测,则任何一个客户端都可以使用颁发给别的客户端的授权码去获取访问令牌,这将产生不良后果。
  • 精确匹配是唯一始终安全的重定向URI核验算法。
  • 授权服务器需要验证最初授权传入的redirect_uri与令牌请求传入的redirect_uri一致。
  • 调用撤回令牌请求时如果授权服务器未找到令牌或者不允许出示令牌的客户端撤回该令牌,授权服务器还是会返回操作成功。为什么不返回失败呢?这是因为,如果这样做了,可能会无意中向客户端透露本不属于它的令牌。

OAuth2细节点:

  • scope参数:使用空格分隔的字符串;
  • 授权码许可流程:需结合前端信道和后端信道通信;
  • OAuth2最关键的一个变化就是授权许可,通俗地说就是授权流程,授权码许可类型只是客户端向授权服务器请求令牌的众多方式之一。
  • 授权服务器Token端点,颁发token前授权服务器需要执行多个步骤以确保请求的合法的,首先,它要验证客户端凭据(通过Authorization头部传递)以确保是哪个客户端请求授权。
  • OAuth2授权协议中穿插着身份认证协议,然而,OAuth事务中的授权流程也有几个地方需要使用身份认证:资源拥有者要在授权服务器的授权端点上进行身份认证,客户端要在授权服务器的令牌端点进行身份认证。也可能还有其它的环节需要进行身份认证,视方案而定。我们现在是要在授权协议之上构建身份认证协议,而授权协议本身又依赖身份认证,着是不是有点复杂?这似乎很奇怪,不过请注意,这种方案的一个事实是,用户在授权服务器上执行身份认证,最终用户的原始凭据不会通过OAuth2.0协议传送到客户端应用(RP)。通过限制各方所需的信息,提高了安全性并减少了出现故障的可能,而且还可以跨越安全域。用户直接向单一方进行身份认证,客户端也是一样,不需要扮演其他角色。

OAuth2授权协议映射身份认证协议

  • 客户端映射为依赖方或叫做RP(relying party)
  • 从概念上将授权服务器和受保护资源合并为身份提供方IdP(identity provider)

OpenID Connect

OpenID Connect直接基于OAuth2.0构建,并保持与它兼容,在多数情况下,它与保护其他API的单纯OAuth基础架构部署在一起。除了OAuth2.0之外,OpenID Connect还使用了JOSE规范套件,用于在不同地方传输经过签名和加密的信息。带有JOSE功能的OAuth2.0部署已经离完整的OpenID Connect系统不远了,但是这一点距离异致的差异是巨大的。OpenID Connect在OAuth2.0的基础上添加了一些关键组件。

ID令牌

ID令牌是一个经过签名的JWT,它与普通的OAuth访问令牌一起提供给客户端应用。与访问令牌不同的是,ID令牌是发送给RP的,并且要被它解析。ID令牌是通过令牌端点响应中添加id_token成员来颁发,是在访问令牌基础上的补充,而不是替换访问令牌。

UserInfo端点

它包含了当前用户的基本信息,该端点返回的声名不存在于上述身份认证的处理中,而是提供了一些附加的身份属性,这让该身份认证协议对开发人员更有价值。

posted on 2022-10-19 17:35  bigstrong_code  阅读(250)  评论(0编辑  收藏  举报

导航