客户端 ID 和机密

Client IDs and secrets

Request URL:
POST https://example.com/oauth/token
Request Headers:
  Content-Type: application/x-www-form-urlencoded
Request POST Body:
grant_type=password&username=joebloggs&
   password=password1234&client_id=myclient&client_secret=myclientsecret

Response:
{
  "access_token": "omitted for brevity",
  "token_type": "bearer",
  "expires_in": 1200,
  "refresh_token": "b3cc9c66b86340c5b743f2a7cec9d2f1"
}

我想使用从单页应用程序发送的 JWT 来保护我的 Umbraco web api 端点。我发现 this lib 可以满足我的大部分需求。

由于我使用了 InMemoryOAuthClientStore,文档指出必须在身份验证请求中提供客户端 ID 和密码(我认为这用于匹配商店中的 OAuthClient? ):

client_id = 有效的客户端 ID(仅在配置客户端商店时才需要)

client_secret = 有效的客户端密码(仅当配置了客户端存储且客户端为 "secure" 时才需要)

我想知道它们的用途。如果我使用来自客户端的 AJAX 调用对 https://example.com/oauth/token 进行此授权调用,我需要在客户端存储 ID 和密码。我的直觉告诉我,这不是它的用途。

另一方面,在这种情况下,客户端 ID 和密码与用户凭据一起提供,因此如果没有有效的用户名和密码,它们将毫无价值。

有人请阐明这一点。

使用用户名和密码请求令牌然后将令牌存储在请求端有两个主要原因。

  1. 额外的安全性。 username/password 组合不是随每个一起发送 请求,但每 1200 只请求一次 seconds/minutes.
  2. 处理请求的服务器只需要检查请求的有效性 令牌而不是每个性能重的密码哈希 要求。

还有其他原因,请看下面的链接。

更新

client_id 是应用程序的 public 标识符。 client_secret 是只有应用程序和授权服务器知道的秘密。以下链接中的更多信息。

有些客户能够将某些信息(客户机密)保密,而有些则不能。例如,如果您通过 ajax 直接从 javascript 向 oauth 端点发出请求 - 此客户端不是 "secure"。它无法私密地存储客户端机密,因为任何人都可以直接在 javascript 代码中或通过在浏览器开发工具中观察请求来查看此机密。对于这样的客户端(移动应用程序是另一个例子),在任何流程中使用客户端密码都没有任何意义,包括 "password" 流程。

"secure" 客户端的示例是您拥有的 Web 服务器。因此,您不会直接从 javascript 向 oauth 端点发出请求,而是将凭据发送到您的服务器,然后服务器向 oauth 端点发出请求。这个客户端在某种意义上是 "secure",它能够私密地存储客户端秘密。对于这样的客户来说,要求客户机密是有意义的(我什至需要我说)。

简而言之,您的直觉是正确的 - 您不应该在您的案例中使用客户端密码,因为它没有任何用处。

现在,即使您不使用客户端密码,您仍然可以单独使用 client_id。例如,您可能会为不同的客户发出一组不同的声明。请注意,客户端 ID 是 public 信息,因此您不应仅根据 client_id 做出任何敏感决定 - 它不可信。

另请注意,"password" 流程是最后的手段,只能由您拥有的客户使用,并且在没有其他流程可用时使用。