AADSTS50013:断言签名验证失败。原因 - 没有找到钥匙

问题描述 投票:0回答:1

目前我正在与 MS Azure

on_behalf_of
流作斗争并面临此错误:

{
  "error": "invalid_grant",
  "error_description": "AADSTS50013: Assertion failed signature validation. [Reason - The key was not found., Please visit the Azure Portal, Graph Explorer or directly use MS Graph to see configured keys for app Id '00000000-0000-0000-0000-000000000000'. Review the documentation at https://docs.microsoft.com/en-us/graph/deployments to determine the corresponding service endpoint and https://docs.microsoft.com/en-us/graph/api/application-get?view=graph-rest-1.0&tabs=http to build a query request URL, such as 'https://graph.microsoft.com/beta/applications/00000000-0000-0000-0000-000000000000']. Trace ID: Correlation ID:  Timestamp: 2024-09-25 10:37:05Z",
  "error_codes": [
    50013
  ],
  "timestamp": "2024-09-25 10:37:05Z",
  "trace_id": "",
  "correlation_id": "",
  "error_uri": "https://login.microsoftonline.com/error?code=50013"
}

我在做什么:

  1. 我使用以下命令生成了公钥和私钥:
$ openssl req -newkey rsa -new -nodes -x509 -days 3650 -pkeyopt rsa_keygen_bits:4096 -keyout key.pem -out cert.pem
$ openssl x509 -pubkey -noout -in cert.pem > pubkey.pem
  1. 我已将生成的公钥上传到 Azure,现在我将其添加到应用程序的清单中:
"keyCredentials": [
  {
    "customKeyIdentifier": "IDENTIFIER",
    "displayName": "app-name",
    "endDateTime": "2034-09-22T09:20:28Z",
    "key": null,
    "keyId": "key-uuid",
    "startDateTime": "2024-09-24T09:20:28Z",
    "type": "AsymmetricX509Cert",
    "usage": "Verify"
  }
]
  1. 我收到客户端断言,流程为
    client_credentials
POST https://login.microsoftonline.com/my-app-tenant-id/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id=my-client-id
&client_secret=my-secret
&scope=api://my-client-id/.default

这工作正常,并返回给我一个看起来像这样的令牌:

{
  "typ": "JWT",
  "alg": "RS256",
  "x5t": "",
  "kid": ""
}
{
  "aud": "api://my-client-id",
  "iss": "https://sts.windows.net/my-app-tenant-id/",
  "iat": 1727252274,
  "nbf": 1727252274,
  "exp": 1727256174,
  "aio": "",
  "appid": "my-client-id",
  "appidacr": "1",
  "idp": "https://sts.windows.net/my-app-tenant-id/",
  "oid": "some-value",
  "rh": "",
  "sub": "some-value",
  "tid": "my-app-tenant-id",
  "uti": "",
  "ver": "1.0"
}
  1. 然后我使用生成的私钥来签名
    assertion
    。该断言用作
POST https://login.microsoftonline.com/my-app-tenant-id/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&client_id=my-client-id
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=here-i-put-the-token-received-from-client-credentials-flow
&assertion=here-i-put-the-signed-assertion
&requested_token_use=on_behalf_of
&scope=api://my-client-id/default

这是我签字前的断言:

{
  "iss" : "my-app-tenant-id",
  "customerXRef" : "som-value",
  "aud" : "https://login.microsoftonline.com/my-app-tenant-id/oauth2/v2.0/token"
}

这是我如何签名的(该代码适用于带有 Gravitee 的 OAuth):

String getToken() {
  try {
    var jwsHeader = new JWSHeader.Builder(alg)
          .type(new JOSEObjectType(typ))
          .keyID(kid) // here I put the same value as I have in `keyCredentials.keyId` above
          .build();
    var jwsObject = new JWSObject(jwsHeader, payload);
    var privateKey = RsaKeyConverters.pkcs8().convert(new ByteArrayInputStream(this.privateKey));
    var signer = new RSASSASigner(privateKey);
    jwsObject.sign(signer);
    return jwsObject.serialize();
  } catch (JOSEException e) {
      throw new RuntimeException(e);
  }
}

我的问题是我做错了什么?

我查看了https://login.microsoftonline.com/error?code=50013但没有找到任何线索。

附注根据 @juunas 的建议,我修改了断言的标题,使其看起来像

{
  "typ": "JWT",
  "x5t#s256": "IDENTIFIER",
  "alg": "RS256"
}

其中

IDENTIFIER
keyCredentials.customKeyIdentifier
的值完全相同,但我仍然收到
The key was not found.
错误消息

P.P.S。我发现,在 https://login.microsoftonline.com/my-app-tenant-id/discovery/keys 之后,我看不到我上传的证书。有什么想法吗?

azure oauth-2.0 azure-active-directory
1个回答
0
投票

典型流程是这样的:

  • 用户获得具有原始范围的访问令牌
  • API 充当 OAuth 客户端,将原始令牌交换为具有不同范围的另一个用户级访问令牌

原始代币

您获得了机器级访问令牌,这是代表流程可能失败的一个重要原因。请改为使用用户级访问令牌尝试您的请求。

客户凭证

这些参数代表高级客户端凭证。您的要求看起来不错:

&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=here-i-put-the-signed-assertion

但也许可以尝试简化:

  • 首先使用简单的客户端密钥获取代表流程
  • 然后更新到客户端断言

代表流量

流程的主要部分是在

assertion
参数中提供原始用户级别访问令牌。一旦客户端秘密起作用,您就知道任何剩余的问题都与客户端断言有关:

POST https://login.microsoftonline.com/my-app-tenant-id/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&client_id=my-client-id
&client_secrer=xxx
&requested_token_use=on_behalf_of
&scope=api://my-client-id/default
© www.soinside.com 2019 - 2024. All rights reserved.