来自OAD2流的AAD的access_token错误

时间:2019-05-09 09:16:20

标签: azure oauth-2.0 azure-active-directory

我正在使用多租户应用程序进行OAuth 2.0身份验证代码身份验证流程。 这是我的授权网址: https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=my_id&prompt=consent&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauthorize&response_type=code&scope=openid+offline_access&state=17

一切正常,我收到auth_code。然后,我使用此auth_code向token_url发出请求,并收到很多信息,例如:

  1. token_type
  2. 范围
  3. id_token
  4. access_token
  5. refresh_token
  6. expires_at
  7. ext_expires_in

对我来说似乎很好,但是当我使用access_token对API发出请求时,如下所示: https://management.azure.com/subscriptions/my_sub_id/locations?api-version=2016-06-01 带有标题:

Content-Type:
  - application/json
Authorization:
  - Bearer EwBQA8l6BAAURSN/FHlDW5xN74t6GzbtsBBeBUYAAV1IHgHb4dOWblzfd/YsSuFicAMDYbua17QivnAT9/pIaeKAg3uKsK5VGqWLzjMOUQrCpd7R1RAM6RkzI0u8e4rpO7DISG7qLso5H5+U1jb+38/j1urcwlXMMxhy83ZXmdpkLXpZV+vcOV...

它响应401错误

body:
  encoding: UTF-8
  string: '{"error":{"code":"InvalidAuthenticationToken","message":"The access token is invalid."}}'

说实话,我认为我的access_token出了点问题。对我来说,这似乎不像JWT。文档说它看起来像:

"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCEV1Q..."

但是我的access_token看起来像:

"access_token": "EwBYA8l6BAAURSN/FHlDW5xN74t6GzbtsBBeBUYAAZDe7JE/MPLoAi+Fr+1Xxq5eBe5N9l8Q+c4QjkY5PGEzRnBpPe7+v6h+PLdh1cceBQx+/JsB2QCrYSCt7x/zGsQAhwoY/"

还好吗?

这是我的申请权限: Permissions

1 个答案:

答案 0 :(得分:0)

您在这里遇到的主要问题是,您只要求访问范围openid offline_access的访问令牌。最终的访问令牌将用于Microsoft Graph(https://graph.microsoft.com),而不是Azure REST API(https://management.azure.com)。

为表明您想要给定API的令牌,授权请求中的scope参数应包括您希望应用对该API拥有的委托权限。对于Azure REST API,只有一个委派权限:user_impersonation。 Azure REST API的标识符URI为https://management.azure.com,因此您要使用的范围值为:

openid offline_access https://management.azure.com/user_impersonation

另外两个重要说明:

  1. 您已经发现,将不会总是向您授予访问令牌作为JWT的身份,您可以对其进行解密。访问令牌的格式是签发令牌的服务(在这种情况下为Azure AD或Microsoft帐户)与签发令牌的服务(在本例中为Microsoft Graph)之间的协议。
  2. 您应该始终包含prompt=consentprompt=consent仅在您已经尝试在没有 的情况下登录用户时使用,该用户需要重新提示您同意新权限。

    如果仅在scopes参数中包含所需的范围,Microsoft Identity平台将负责确定是否需要提示同意。如果您始终包含prompt=consent,您会发现许多组织将被阻止访问您的应用程序,因为它们已禁用了用户自己授予同意的功能(并且该参数明确指出您 require < / em>再次提示用户)。