简体   繁体   English

如何在使用 OAuth2 的资源所有者密码凭据授予类型时对客户端凭据保密

[英]How to keep the client credentials confidential, while using OAuth2's Resource Owner Password Credentials grant type

We are building a rest service and we want to use OAauth 2 for authorization.我们正在构建 rest 服务,我们希望使用 OAauth 2 进行授权。 The current draft (v2-16 from May 19th) describes four grant types .当前的草案(5 月 19 日的 v2-16)描述了四种资助类型 They are mechanisms or flows for obtaining authorization (an access token).它们是获取授权(访问令牌)的机制或流程。

  1. Authorization Code授权码
  2. Implicit Grant隐式授权
  3. Resource Owner Credentials资源所有者凭证
  4. Client Credentials客户凭证

It seems we need to support all four of them, since they serve different purposes.看来我们需要支持所有四个,因为它们服务于不同的目的。 The first two (and possibly the last one) can be used from third-party apps that need access to the API.前两个(也可能是最后一个)可以从需要访问 API 的第三方应用程序中使用。 The authorization code is the standard way to authorize a web application that is lucky enough to reside on a secure server, while the implicit grant flow would be the choice for a client application that can't quite keep its credentials confidential (eg mobile/desktop application, JavaScript client, etc.).授权代码是授权 web 应用程序的标准方法,该应用程序幸运地驻留在安全服务器上,而隐式授权流将是不能完全保密其凭据的客户端应用程序的选择(例如移动/桌面应用程序,JavaScript 客户端等)。
We want to use the third mechanism ourselves to provide a better user experience on mobile devices – instead of taking the user to a login dialog in a web browser and so on, the user will simply enter his or her username and password directly in the application and login.我们希望自己使用第三种机制来在移动设备上提供更好的用户体验——而不是将用户带到 web 浏览器等中的登录对话框,用户只需直接在应用程序中输入他或她的用户名和密码并登录。 We also want to use the Client Credentials grant type to obtain an access token that can be used to view public data, not associated with any user.我们还想使用 Client Credentials 授权类型来获取可用于查看公共数据的访问令牌,不与任何用户关联。 In this case this is not so much authorization, but rather something similar to an API key that we use to give access only to applications that have registered with us, giving us an option to revoke access if needed.在这种情况下,这不是太多的授权,而是类似于 API 密钥的东西,我们使用该密钥仅授予已向我们注册的应用程序的访问权限,从而使我们可以在需要时撤销访问权限。

So my questions are:所以我的问题是:

  1. Do you think I have understood the purpose of the different grant types correctly?您认为我正确理解了不同资助类型的目的吗?
  2. How can you keep your client credentials confidential?您如何对客户凭证保密? In both the third and fourth case, we need to have the client id and client secret somewhere on the client, which doesn't sound like a good idea.在第三种和第四种情况下,我们都需要在客户端的某个地方拥有客户端 ID 和客户端密码,这听起来不是一个好主意。
  3. Even if you use the implicit grant type and you don't expose your client secret, what stops another application from impersonating your app using the same authorization mechanism and your client id?即使您使用隐式授权类型并且不公开您的客户端密码,有什么可以阻止另一个应用程序使用相同的授权机制和您的客户端 ID 来模拟您的应用程序?

To summarize, we want to be able to use the client credentials and resource owner credentials flow from a client application.总而言之,我们希望能够使用来自客户端应用程序的客户端凭据和资源所有者凭据流。 Both of these flows require you to store the client secret somehow, but the client is a mobile or JavaScript application, so these could easily be stolen.这两个流程都需要您以某种方式存储客户端密码,但客户端是移动应用程序或 JavaScript 应用程序,因此很容易被窃取。

I'm facing similar issues, and am also relatively new to OAuth.我面临着类似的问题,而且对 OAuth 也比较陌生。 I've implemented "Resource Owner Password Credentials" in our API for our official mobile app to use -- the web flows just seem like they'd be so horrible to use on a mobile platform, and once the user installs an app and trusts that it's our official app, they should feel comfortable typing username/password directly into the app.我已经在我们的 API 中实现了“资源所有者密码凭据”,供我们的官方移动应用程序使用——web 流看起来就像它们在移动平台上使用起来太可怕了,一旦用户安装了应用程序并信任这是我们的官方应用程序,他们应该觉得直接在应用程序中输入用户名/密码很舒服。

The problem is, as you point out, there is no way for my API server to securely verify the client_id of the app.问题是,正如您所指出的,我的 API 服务器无法安全地验证应用程序的 client_id。 If I include a client_secret in the app code/package, then it's exposed to anyone who installs the app, so requiring a client_secret wouldn't make the process any more secure.如果我在应用程序代码/包中包含 client_secret,那么它会暴露给任何安装该应用程序的人,因此要求 client_secret 不会使该过程更加安全。 So basically, any other app can impersonate my app by copying the client_id.所以基本上,任何其他应用程序都可以通过复制 client_id 来模拟我的应用程序。

Just to direct answers at each of your points:只是为了直接回答你的每一点:

  1. I keep re-reading different drafts of the spec to see if anything's changed, and am focused mostly on the Resource Owner Password Credentials section, but I think you're correct on these.我不断重新阅读规范的不同草稿以查看是否有任何更改,并且主要关注资源所有者密码凭据部分,但我认为您在这些方面是正确的。 Client Credentials(4) I think could also be used by an in-house or third-party service that might need access to more than just "public" information, like maybe you have analytics or something that need to get information across all users. Client Credentials(4) 我认为也可以由内部或第三方服务使用,这些服务可能需要访问的不仅仅是“公共”信息,比如您可能有分析或需要获取所有用户信息的东西。

  2. I don't think you can keep anything confidential on the client.我认为你不能对客户保密。

  3. Nothing stops someone else from using your client id.没有什么能阻止其他人使用您的客户 ID。 This is my issue too.这也是我的问题。 Once your code leaves the server and is either installed as an app or is running as Javascript in a browser, you can't assume anything is secret.一旦您的代码离开服务器并作为应用程序安装或在浏览器中作为 Javascript 运行,您就不能假设任何事情都是秘密的。

For our website, we had a similar issue to what you describe with the Client Credentials flow.对于我们的网站,我们遇到了与您描述的客户凭证流程类似的问题。 What I ended up doing is moving the authentication to the server side.我最终做的是将身份验证移至服务器端。 The user can authenticate using our web app, but the OAuth token to our API is stored on the server side, and associated with the user's web session. The user can authenticate using our web app, but the OAuth token to our API is stored on the server side, and associated with the user's web session. All API requests that the Javascript code makes are actually AJAX calls to the web server.所有 API 请求 Javascript 代码实际上都是对 Z2567A5EC9705EB7AC2C984033E06 服务器的 AJAX 调用。 So the browser isn't directly authenticated with the API, but instead has an authenticated web session.所以浏览器没有直接使用 API 进行身份验证,而是有一个经过身份验证的 web session。

It seems like your use-case for Client Credentials is different, in that you're talking about third-party apps, and are only serving public data through this method.您的客户端凭据的用例似乎有所不同,因为您在谈论第三方应用程序,并且仅通过此方法提供公共数据。 I think your concerns are valid (anyone can steal and use anyone else's API key), but if you only require a free registration to get an API key, I don't see why anyone would really want to steal one.我认为您的担忧是正确的(任何人都可以窃取和使用其他人的 API 密钥),但如果您只需要免费注册即可获得 API 密钥,我不明白为什么有人真的想偷一个。

You could monitor/analyze the usage of each API key to try to detect abuse, at which point you could invalidate one API key and give the legitimate user a new one.您可以监控/分析每个 API 密钥的使用情况以尝试检测滥用情况,此时您可以使一个 API 密钥无效并为合法用户提供一个新密钥。 This might be the best option, but it's in no way secure.这可能是最好的选择,但它绝不安全。

You could also use a Refresh Token-like scheme for this if you wanted to lock it up a bit tighter, although I don't know how much you would really gain.如果您想将其锁定得更紧,您也可以为此使用类似 Refresh Token 的方案,尽管我不知道您会真正获得多少。 If you expired the Javascript-exposed api tokens once a day and required the third-party to do some sort of server-side refresh using a (secret) refresh token, then stolen api tokens would never be good for more than a day.如果您每天使 Javascript 公开的 api 令牌过期一次,并要求第三方使用(秘密)刷新令牌进行某种服务器端刷新,那么被盗的 api 令牌将永远不会超过一天。 Might encourage potential token thieves to just register instead.可能会鼓励潜在的令牌窃贼只注册。 But sort of a pain for everyone else, so not sure if this is worth it.但对其他人来说有点痛苦,所以不确定这是否值得。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring安全性Oauth2资源所有者密码凭证授权 - Spring security Oauth2 Resource Owner Password Credentials Grant 如何使用oAuth2“资源所有者凭证授予” IOS APP? - How to use oAuth2 “Resource owner credentials grant” IOS APP? 安全Oauth 2.0资源所有者密码凭据授予类型 - Secure Oauth 2.0 Resource Owner Password Credentials Grant Type Django-OAuth-ToolKit:使用 OAuth2.0 的客户端凭据授予类型为多个资源/服务生成访问令牌 - Django-OAuth-ToolKit : Generating access token's for multiple resources/services using client credentials grant type of OAuth2.0 如何解决由无效的OAuth 2授权类型CLIENT_CREDENTIALS引起的invalid_request? - How to solve invalid_request caused by Invalid OAuth 2 grant type: CLIENT_CREDENTIALS? OAuth2资源所有者密码流安全性 - OAuth2 Resource Owner Password flow security 为什么OAuth2服务器不提供refresh_token响应“client_credentials”授权? - Why is a refresh_token not provided by OAuth2 servers responding to a “client_credentials” grant? 使用 OAuth2.0 资源所有者密码凭证访问安全的 API - Use OAuth2.0 Resource Owner Password credentials to access a secured API 没有资源所有者授权的OAuth2隐式授予 - OAuth2 Implicit Grant wihtout resource owner authorisation OAuth2是否允许使用非密码或自定义凭据进行授权? - Does OAuth2 allow for authorization using non-password or custom credentials?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM