アプリケーション用に OpenID フローをセットアップしており、Microsoft Active Directory を使用して秘密鍵 JWT クライアント証明書認証をテストしたいと考えています。つまり、ID とアクセス トークンを要求するときに、クライアント シークレットではなく証明書を使用してアプリケーションを認証したいと考えています。ただし、トークン要求を行うと、次のエラーが表示されます。
{
"error":"invalid_client",
"error_description":"AADSTS700027: Client assertion contains an invalid signature. [Reason - The key was not found., Please visit 'https://developer.microsoft.com/en-us/graph/graph-explorer' and query for 'https://graph.microsoft.com/beta/applications/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' to see configured keys]\r\nTrace ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\r\nCorrelation ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\r\nTimestamp: 2019-09-26 22:24:19Z",
"error_codes":[
700027
],
"timestamp":"2019-09-26 22:24:19Z",
"trace_id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"correlation_id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"error_uri":"https://login.microsoftonline.com/error?code=700027"
}
次のコマンドを使用して、秘密鍵と証明書を生成しています。
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes
cert.pem
Azure ポータルのアプリ登録にアップロードしました。
私のアプリケーションでは、Nimbus JOSE + JWTライブラリを使用して JWT を構築し、Nimbus OAuth 2.0 SDK と OpenID Connect 拡張機能を使用して OpenID フローを管理しています。それぞれのパッケージの Javadoc ページは次のとおりです。
- https://www.javadoc.io/doc/com.nimbusds/nimbus-jose-jwt/7.8
- https://www.javadoc.io/doc/com.nimbusds/oauth2-oidc-sdk/6.14
ヘッダーと対応するフッター-----BEGIN PRIVATE KEY-----
が含まれていることを確認することで、キーと証明書が PEM 形式であることを確認しました。-----BEGIN CERTIFICATE-----
エラーに従って、https://developer.microsoft.com/en-us/graph/graph-explorerにアクセスし、左側にログインしてから、指定された編集されていない URL を使用してクエリを送信しました。これを行うと、エラーが発生しました:
{
"error": {
"code": "Request_ResourceNotFound",
"message": "Resource 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' does not exist or one of its queried reference-property objects are not present.",
"innerError": {
"request-id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"date": "2019-09-26T23:47:37"
}
}
私の現在の実装は次のようになります。
val privateKeyString = File(keyFilePath).readText()
val certificateString = File(certFilePath).readText()
val certObject = JWK.parseFromPEMEncodedX509Cert(certificateString)
val privateKeyJWK = JWK.parseFromPEMEncodedObjects(privateKeyString)
val privateKey = RSAKey.parse(privateKeyJWK.toJSONObject())
val privateKeyJWT = PrivateKeyJWT(
ClientID(configuration.clientId), // clientId retrieved from the app reg on the azure portal
providerMetadata.tokenEndpointURI, // login.microsoftonline.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/oauth2/token
JWSAlgorithm.RS256,
privateKey.toRSAPrivateKey(),
certObject.keyID,
null)
val tokenReq = TokenRequest(
providerMetadata.tokenEndpointURI,
privateKeyJWT,
AuthorizationCodeGrant(authCode, // authCode received from previous step of the OpenID flow
URI(configuration.redirectURI)) // the application's login page. This has been registered in
// the app reg on the azure portal.
)
val tokenHTTPResponse: HTTPResponse? = tokenReq.toHTTPRequest().send()
val tokenResponse = OIDCTokenResponse.parse(tokenHTTPResponse) // response fails with the described error
ここで間違っている可能性のある手順がいくつかありますが、絞り込むことができませんでした。
- キーの生成が間違っている可能性があります。おそらく、想定された形式ではないキーと証明書を使用していますか?
- Nimbus ライブラリを使用したキーの解析が間違っている可能性があります。リクエスト中にコードをステップ実行してデータ オブジェクトを調べると、ファイルからすべてのコンポーネントを解析しているように見えます。これらのコンポーネントを正しく解析しているかどうかは不明です。
- 秘密鍵 JWT の構成に問題がある可能性があります。
- トークン リクエストの構成に問題がある可能性があります。
- Azure Portal でのアプリケーション登録の構成が間違っている可能性があります。
これを絞り込む方法、またはこの問題を解決する方法についての指針をいただければ幸いです。