如何验证资源服务器的OAuth 2.0访问令牌?

如何验证资源服务器的OAuth 2.0访问令牌?,oauth,oauth-2.0,Oauth,Oauth 2.0,当客户端要求资源服务器使用OAuth 2.0访问令牌获取受保护的资源时,该服务器如何验证令牌?OAuth 2.0刷新令牌协议?于2015年11月更新:根据下面的Hans Z.-这现在确实被定义为协议的一部分 原始答案:OAuth 2.0规范()没有明确定义用于访问令牌(AT)验证的资源服务器(RS)和授权服务器(AS)之间的交互。这实际上取决于AS的令牌格式/策略-一些令牌是自包含的(如),而其他令牌可能类似于会话cookie,因为它们只引用服务器端保留在AS的信息 在OAuth工作组中,已经有

当客户端要求资源服务器使用OAuth 2.0访问令牌获取受保护的资源时,该服务器如何验证令牌?OAuth 2.0刷新令牌协议?

于2015年11月更新:根据下面的Hans Z.-这现在确实被定义为协议的一部分

原始答案:OAuth 2.0规范()没有明确定义用于访问令牌(AT)验证的资源服务器(RS)和授权服务器(AS)之间的交互。这实际上取决于AS的令牌格式/策略-一些令牌是自包含的(如),而其他令牌可能类似于会话cookie,因为它们只引用服务器端保留在AS的信息


在OAuth工作组中,已经有关于创建RS与AS进行AT验证通信的标准方法的讨论。我的公司(Ping Identity)为我们的商业OAuth提出了一种方法(Ping Federate):。它为此使用基于REST的交互,这是对OAuth 2.0的补充。

OAuth v2规范指出:

访问令牌属性和用于访问受保护资源的方法超出了本规范的范围,由配套规范定义

我的授权服务器有一个webservice(SOAP)端点,允许资源服务器知道访问令牌是否有效。

Google way

请求:

https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=1/fFBGRNJru1FQd44AzqT3Zg
GET /applications/:client_id/tokens/:access_token
答复:

{
  "audience":"8819981768.apps.googleusercontent.com",
  "user_id":"123456789",
  "scope":"https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
  "expires_in":436
} 
{
  "id": 1,
  "url": "https://api.github.com/authorizations/1",
  "scopes": [
    "public_repo"
  ],
  "token": "abc123",
  "app": {
    "url": "http://my-github-app.com",
    "name": "my github app",
    "client_id": "abcde12345fghij67890"
  },
  "note": "optional note",
  "note_url": "http://optional/note/url",
  "updated_at": "2011-09-06T20:39:23Z",
  "created_at": "2011-09-06T17:26:27Z",
  "user": {
    "login": "octocat",
    "id": 1,
    "avatar_url": "https://github.com/images/error/octocat_happy.gif",
    "gravatar_id": "somehexcode",
    "url": "https://api.github.com/users/octocat"
  }
}
微软之路

Github路

请求:

https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=1/fFBGRNJru1FQd44AzqT3Zg
GET /applications/:client_id/tokens/:access_token
答复:

{
  "audience":"8819981768.apps.googleusercontent.com",
  "user_id":"123456789",
  "scope":"https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
  "expires_in":436
} 
{
  "id": 1,
  "url": "https://api.github.com/authorizations/1",
  "scopes": [
    "public_repo"
  ],
  "token": "abc123",
  "app": {
    "url": "http://my-github-app.com",
    "name": "my github app",
    "client_id": "abcde12345fghij67890"
  },
  "note": "optional note",
  "note_url": "http://optional/note/url",
  "updated_at": "2011-09-06T20:39:23Z",
  "created_at": "2011-09-06T17:26:27Z",
  "user": {
    "login": "octocat",
    "id": 1,
    "avatar_url": "https://github.com/images/error/octocat_happy.gif",
    "gravatar_id": "somehexcode",
    "url": "https://api.github.com/users/octocat"
  }
}
亚马逊之路

请求:

https://api.amazon.com/auth/O2/tokeninfo?access_token=Atza|IQEBLjAsAhRmHjNgHpi0U-Dme37rR6CuUpSR...
答复:

HTTP/l.l 200 OK
Date: Fri, 3l May 20l3 23:22:l0 GMT 
x-amzn-RequestId: eb5be423-ca48-lle2-84ad-5775f45l4b09 
Content-Type: application/json 
Content-Length: 247 

{ 
  "iss":"https://www.amazon.com", 
  "user_id": "amznl.account.K2LI23KL2LK2", 
  "aud": "amznl.oa2-client.ASFWDFBRN", 
  "app_id": "amznl.application.436457DFHDH", 
  "exp": 3597, 
  "iat": l3ll280970
}

更新@Scott T.的答案:2015年10月,IETF RFC 7662标准化了用于令牌验证的资源服务器和授权服务器之间的接口,请参见:。示例验证调用如下所示:

POST /introspect HTTP/1.1
Host: server.example.com
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer 23410913-abewfq.123483

token=2YotnFZFEjr1zCsicMWpAA
和一个样本响应:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "active": true,
  "client_id": "l238j323ds-23ij4",
  "username": "jdoe",
  "scope": "read write dolphin",
  "sub": "Z5O3upPC88QrAjx00dis",
  "aud": "https://protected.example.net/resource",
  "iss": "https://server.example.com/",
  "exp": 1419356238,
  "iat": 1419350238,
  "extension_field": "twenty-seven"
}

当然,供应商和产品的采用将随着时间的推移而发生。

OAuth 2.0规范没有定义部件。但可能有两种选择:

  • 当资源服务器在Authz头中获取令牌时,它调用Authz服务器上的validate/introspect API来验证令牌。在这里,Authz服务器可以通过使用DB-Store或验证签名和某些属性来验证它。作为响应的一部分,它解码令牌并发送令牌的实际数据以及剩余的到期时间

  • Authz服务器可以使用私钥加密/签名令牌,然后将公钥/证书提供给资源服务器。当资源服务器获得令牌时,它或者解密/验证签名以验证令牌。取出内容并处理令牌。然后,它可以提供访问或拒绝

  • 2021年最新答案 通常不建议您自己滚动OAuth 2/OIDC实现的任何部分,尤其是现在标记内省已经过时。与尝试使用自己的加密库非常相似,使用如此复杂的规范很容易犯严重错误

    实现OAuth 2的其他语言中的推荐库。已被OpenID基金会认证的;许多库还实现了OAuth 2

    如果您在.NET中使用IdentityServer库(版本2.2及更高版本),则可以完全实现这一点。它作为(也是)的一部分发布,并且是资源服务器可以验证访问令牌的端点


    如果你已经走到了这一步,但你仍然真的想拥有自己的令牌,那么请从中学习一些技巧。

    服务器应该能够验证它之前自己发布的令牌。。。通常这将是数据库查找或加密(自签名令牌)。在这种情况下,资源所有者WS和客户端WS都位于不同的设备上,您是指身份验证服务和资源服务吗?(客户机/消费者将始终位于不同的设备上,并且自己无法验证令牌)如果是这种情况,您可以使用“昂贵”的刷新令牌进行检查(只有auth server可以这样做)但是长寿命的访问令牌经常过期,并且可以脱机检查。如果使用OoenId Connect,我们不应该使用openid方式使用id令牌验证访问令牌:@Renan:与授权请求中请求作用域的方式一致,它带有一个
    范围
    查询参数,该参数的值包含一个以空格分隔的范围列表。如果某项内容尚未被管理机构正式接受,请不要使用“标准化”一词。截至2018年2月的IETF RFC 7662明确表示这是一个“提案”。@adnankamili没有“提案”这回事。当一个文档成为RFC时,它已经是一个“提议的标准”,在其背后具有重要的影响力。OAuth 2.0本身仍然是一个“建议的标准”,所以我不确定您想表达什么观点。如果OAuth被认为是一个“三段式”身份验证,那么这个内省调用会是第三段吗?我错误地将“第三段”归因于客户端调用授权服务器以交换访问令牌的身份验证代码。Scott T,有没有办法查看关于如何在Ping Federate中使用该功能的代码示例?@JavaHead我们的开发人员网站上介绍了更多协议细节:,PingFederate OAuth作为一组JSP发布,这些JSP可以作为验证令牌的源代码引用。它(以及其他开源库和示例)可以从这里下载:Scott,我正在寻找一个示例,该示例将演示如何使用Rest API授予客户端凭据,并由本地资源服务器和PingFederate作为身份验证服务器进行保护。然后,本地资源服务器将调用验证端点。你遇到过类似的事情吗?@JavaHead这是你应该能够参考PingFederate OAuth游乐场的东西。它演示了客户端凭据授予类型和资源服务器对访问令牌的验证。@Gary您是corr