错误:在尝试获取Onedrive访问令牌时,公共客户端无法发送客户端密钥。

8
我正在尝试通过以下URL获取OneDrive访问令牌:

https://login.live.com/oauth20_token.srf?client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&redirect_uri=https://login.live.com/oauth20_desktop.srf&code=AUTHORIZATION_CODE&grant_type=authorization_code

但是响应如下所示:

{"error":"invalid_request","error_description":"Public clients can't send a client secret."}

有人能解释一下吗?此错误是由于您的客户端被标记为“公共客户端”,这意味着您不能使用客户端密码(client secret),替代方案是使用重定向URI作为身份验证。

你是在创建一个网页应用程序、移动/桌面应用程序,还是只是在尝试 API? - Kevin Lam
2个回答

11
“公共客户端”是指移动或桌面应用程序(网络服务是“机密客户端”)。MSA给出此响应,因为您正在重定向到https://login.live.com/oauth20_desktop.srf。在这种情况下,您不应该在请求中提供client_secret值,因此您的请求应该像这样:

https://login.live.com/oauth20_token.srf?client_id=YOUR_CLIENT_ID&redirect_uri=https://login.live.com/oauth20_desktop.srf&code=AUTHORIZATION_CODE&grant_type=authorization_code


3
一个来自更近期的例子:

https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow

使用客户端密钥请求访问令牌
现在您已经获取了一个授权码并获得了用户的许可,您可以兑换该代码以获取资源的访问令牌。通过向/token端点发送POST请求来兑换代码:
// Line breaks for legibility only

POST /{tenant}/oauth2/v2.0/token HTTP/1.1 Host:
https://login.microsoftonline.com Content-Type:
application/x-www-form-urlencoded
 
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fmail.read
&code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr...
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&grant_type=authorization_code
&code_verifier=ThisIsntRandomButItNeedsToBe43CharactersLong 
&client_secret=JqQX2PNo9bpM0uEihUPzyrh    // NOTE: Only required for web apps. This secret needs to be URL-Encoded.

参数 必填/可选 描述
tenant 必填 请求路径中的{tenant}值可以用于控制谁可以登录应用程序。有效值为common、organizations、consumers和租户标识符。有关更多信息,请参阅终结点。
client_id 必填 Azure门户-应用程序注册页面分配给您的应用程序的应用程序(client) ID。
scope 可选 一个以空格分隔的范围列表。这些范围必须全部来自单个资源,并且包括OIDC范围(profile、openid、email)。有关更多信息,请参阅Microsoft身份平台中的权限和同意。此参数是授权代码流程的Microsoft扩展,旨在允许应用程序在令牌赎回期间声明它们想要的资源。
code 必填 您在流程的第一步获得的授权代码(authorization_code)。
redirect_uri 必填 与获取授权代码时使用的相同的redirect_uri值。
grant_type 必填 必须为authorization_code,适用于授权代码流程。
code_verifier 推荐 与获取授权代码时使用的相同的code_verifier。如果在授权代码授予请求中使用了PKCE,则需要此参数。有关更多信息,请参阅PKCE RFC。
client_secret 机密Web应用程序必填 您在应用注册门户中为应用程序创建的应用程序密钥。不要在本地应用程序或单页应用程序中使用应用程序密钥,因为客户端密钥无法可靠地存储在设备或网页上。它对于Web应用程序和Web API是必需的,可以在服务器端安全地存储客户端密钥。像这里的所有参数一样,在发送之前必须对客户端密钥进行URL编码。通常由SDK完成此步骤。有关URI编码的更多信息,请参阅URI通用语法规范。RFC 6749中提供的在Authorization标头中提供凭据的基本身份验证模式也受支持。
因此,如果您正在创建桌面或移动应用程序,并且在Azure门户中将其注册为此类应用程序https://portal.azure.com/,那么如果您发送client_secret,则会收到特定的错误。因此,您必须从POST请求中删除它,以成功地交换接收到的代码以获取身份验证令牌和刷新令牌。请注意,机密的Web应用程序是唯一需要发送client_secret的类型。其他类型的注册应用程序或公共应用程序不应发送client_secret。

该代码有效期为10分钟,因此必须立即使用类似上述的请求交换身份验证令牌。

还要注意一件事:

是否需要发送client_secret取决于您是否已将应用程序在AzureAD中注册为“Web”(需要发送client_secret)或“本机应用程序”(不需要发送client_secret)。因此,您的实现将取决于您所做的注册。您可以在AzureAD中更改应用程序类型 -> 应用程序注册 -> 从左侧菜单选择身份验证。在平台配置下选择您的特定平台。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接