我正在为我的应用程序设置一个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 with OpenID Connect extensions来管理OpenID流。以下分别是每个软件包的Javadoc页面:
我通过检查密钥和证书是否包含-----BEGIN PRIVATE KEY-----
和-----BEGIN CERTIFICATE-----
标头以及相应的页脚来验证PEM格式。
根据错误,我访问了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
这里有几个步骤可能会出错,但我无法缩小范围:
任何有关如何缩小范围或解决此问题的指针将不胜感激!
答案 0 :(得分:0)
为什么不起作用的简单答案是Azure Active Directory不支持私钥JWT身份验证。编写的代码有效,但仅适用于支持私钥JWT身份验证的服务。
答案 1 :(得分:0)
从Nimbus JOSE + JWT库生成JWK的方法比较简单:
https://connect2id.com/products/nimbus-jose-jwt/examples/jwk-generation#rsa
您的OAuth 2.0客户端是否在令牌端点上注册了private_key_jwt
身份验证?