AWS 认知;命中 /oauth2/token 时出现未授权客户端错误
Posted
技术标签:
【中文标题】AWS 认知;命中 /oauth2/token 时出现未授权客户端错误【英文标题】:AWS Cognito; unauthorized_client error when hitting /oauth2/token 【发布时间】:2018-10-20 05:44:31 【问题描述】:目前采取的步骤:
在 cognito 中设置新用户池 生成一个没有秘密的应用客户端;我们称它为 iduser_pool_client_id
在user_pool_client_id
的用户池客户端设置下,选中“Cognito 用户池”框,添加 https://localhost
作为回调并退出 url,选中“授权码授予”、“隐式授予”和“允许”下的所有内容OAuth 范围"
创建域名;我们就叫它user_pool_domain
使用用户名/密码创建一个新用户
现在,我可以成功前往:
https://user_pool_domain.auth.us-east-2.amazoncognito.com/oauth2/authorize?response_type=code&client_id=user_pool_client_id&redirect_uri=https%3A%2F%2Flocalhost
这为我提供了一个登录页面,我可以作为我的用户登录,这会将我返回到https://localhost/?code=code_uuid
然后我尝试以下操作:
curl -X POST https://user_pool_domain.auth.us-east-2.amazoncognito.com/oauth2/token -H 'Content-Type: application/x-www-form-urlencoded' -d 'grant_type=authorization_code&redirect_uri=https%3A%2F%2Flocalhost&code=code_uuid&client_id=user_pool_client_id'
但是,这只会返回以下内容:
"error":"unauthorized_client"
token endpoint docs 说unauthorized_client
是因为“不允许客户端进行代码授权流程或刷新令牌”。这令人困惑,因为我选中了允许客户端使用代码授权流程的框。
【问题讨论】:
正如 Andrew 所指出的,当redirect_uri
出现问题时,您会收到此错误。使用 localhost 对我来说从来都不是问题,但是当我在调用 token
端点时省略 redirect_uri
上的尾部斜杠时,我确实会收到这个(相当误导性的)错误消息。您可以尝试将%2F
添加到redirect_uri
的末尾吗?
@MikePatrick 哇,非常感谢!这是缺少的尾部斜杠。这是一个令人沮丧的错误消息,我错过了一天,但它现在确实有效!!!
我发现如果我在 AWS 端的应用程序客户端中定义了一个重定向 uri 列表,这也成立 - 当我用单个项目替换列表并让客户端引用单个项目,它工作。否则,我收到了提到的 redirect_uri 错误。
【参考方案1】:
因此,用户池必须有一个斜杠 (https://localhost/
),然后必须在所有回调 URL 中使用该斜杠。然后它决定工作!
【讨论】:
你拯救了我的一天。redirect_uri
应该和我们在 Cognito 控制台中定义的完全一样
同意@rioastamal 所说的。不需要尾随斜杠,但 redirect_uri 应与用户池中为“回调 URL”定义的完全相同,例如:https://**DOMAINPREFIX**.auth.**REGION**.amazoncognito.com/ oauth2/token?grant_type=authorization_code&client_id=**CLIENTID**&code=**AUTHORIZATION_CODE_OBTAINED_FROM_oauth2/authorize_ENDPOINT**&redirect_uri=**CALLBACK_URL_CONFIGURED_IN_USERPOOL**
@kiran01bm 大声笑这是我的配置的问题。感谢您指出。我终于可以睡觉了……
这是随机的,没有在 amazon cognito 中记录,非常感谢!这也适用于自定义域和 URL:https://example.test/login/
【参考方案2】:
在我看来一切正常。我认为它可能在抱怨 Authorization 标头丢失但不确定。您可以尝试一些方法:
1) 根据此页面 (https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html),您不需要在令牌请求中发送 Authorization 标头,但也许仍然需要它。您可以尝试仅传递其中的客户端 ID(授权 [客户端 ID])或配置一个秘密并尝试传递授权 [客户端 ID:客户端秘密],就像它说的那样)。无论如何,使用客户端密钥进行授权代码流通常是有意义的,因为在此流中,有一个服务器端组件可以安全地处理令牌交换。
2) 尝试使用隐式流来查看是否有效。隐式流对于没有服务器端组件的单页应用程序是有意义的。为此,不需要客户端密码。
【讨论】:
我已经尝试过将 clientID:clientSecret base64 编码为 Authorization 标头,但没有成功。我将如何使用隐式流程?有什么区别? 我注意到如果重定向 URI 不可访问,AWS API Gateway 将抛出“未授权”错误。现在想来,尝试使用 localhost 可能是个问题。想想看……AWS 需要重定向到该页面,但它不能,因为 localhost 在您的本地计算机上。我会尝试使用非本地 URL 来查看是否是导致问题的原因。 授权码流和隐式流的区别如下:***.com/questions/16321455/… 如果你想使用隐式流,那么它与你刚才所做的类似,只是不需要最后一步。相反,您会从第一个请求中收到令牌。它在所谓的 URL 片段中提供。 URL 片段只能由浏览器读取。此片段包含令牌。【参考方案3】:如果您使用 amplify 并在 CLI 之外对其进行了配置,并且其他答案对您不起作用,那么您可以尝试的最后一个修复方法是确保您有 responseType: 'token' 如果您使用的是隐式流。为我解决了问题。
Auth:
oauth:
domain : 'your-app.auth.your-region.amazoncognito.com',
redirectSignIn: environment.cognito.oauthCallbackLogin,
redirectSignOut: environment.cognito.oauthCallbackLogout,
responseType: 'token',
scope : ['email', 'openid', 'profile'],
【讨论】:
或使用Authorization code grant
时确保responseType为code
【参考方案4】:
确保在请求中也包含范围。像下面这样
https://domain.auth.eu-central-1.amazoncognito.com/signup?client_id=&response_type=token&scope=aws.cognito.signin.user.admin+email+openid+phone+profile&redirect_uri=https://www.google.com/
【讨论】:
以上是关于AWS 认知;命中 /oauth2/token 时出现未授权客户端错误的主要内容,如果未能解决你的问题,请参考以下文章
如何在使用 oauthlib.oauth2 fetch_token 时捕获 API 失败
谷歌 oauth2 id_token 与 refresh_token
来自客户端 javascript 的错误 400 Cognito /oauth2/token 端点