title: How to fix "Invalid Signature" API error when submitting a token request in OpenID flow?
body: <p>I'm setting up an OpenID flow for my application and want to test Private Key JWT client certificate authentication with Microsoft Active Directory. That is, I want to use a certificate rather than client secrets to authenticate my application when requesting id and access tokens. However, when making the token request I receive the following error:</p>
  
  <pre><code>{
     "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"
  }
  </code></pre>
  
  <p>I'm generating the private key and certificate using the following command:</p>
  
  <pre><code>openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes
  </code></pre>
  
  <p>I've uploaded <code>cert.pem</code> to my app registration in the azure portal.</p>
  
  <p>In my application, I'm using the <a href="https://connect2id.com/products/nimbus-jose-jwt" rel="nofollow noreferrer">Nimbus JOSE + JWT</a> library to construct the JWT and the <a href="https://connect2id.com/products/nimbus-oauth-openid-connect-sdk" rel="nofollow noreferrer">Nimbus OAuth 2.0 SDK with OpenID Connect extensions</a> to manage the OpenID flow. Here are the Javadoc pages for each of those packages respectively:</p>
  
  <ul>
  <li><a href="https://www.javadoc.io/doc/com.nimbusds/nimbus-jose-jwt/7.8" rel="nofollow noreferrer">https://www.javadoc.io/doc/com.nimbusds/nimbus-jose-jwt/7.8</a></li>
  <li><a href="https://www.javadoc.io/doc/com.nimbusds/oauth2-oidc-sdk/6.14" rel="nofollow noreferrer">https://www.javadoc.io/doc/com.nimbusds/oauth2-oidc-sdk/6.14</a></li>
  </ul>
  
  <p>I've verified that the key and certificate are in the PEM format by checking that they contain the <code>-----BEGIN PRIVATE KEY-----</code> and <code>-----BEGIN CERTIFICATE-----</code> headers and the corresponding footers.</p>
  
  <p>As per the error, I visited <a href="https://developer.microsoft.com/en-us/graph/graph-explorer" rel="nofollow noreferrer">https://developer.microsoft.com/en-us/graph/graph-explorer</a> , logged in on the left, and then sent a query using the given unredacted url. Doing this gave me the error:</p>
  
  <pre><code>{
  "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"
      }
  }
  </code></pre>
  
  <p>My current implementation looks as follows.</p>
  
  <pre><code>        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
  </code></pre>
  
  <p>There are several steps that could be going wrong here but I haven't been able to narrow it down:</p>
  
  <ul>
  <li>My Key generation could be wrong. Perhaps I am using a key and cert that is not the expected format?</li>
  <li>My parsing of the keys using the Nimbus Library could be wrong. Stepping through the code during a request and inspecting the data objects seems to indicate that it is parsing all the components out of the file. Whether or not it is parsing those components correctly is unclear.</li>
  <li>My construction of the Private Key JWT may be flawed.</li>
  <li>The construction of the Token Request may be flawed.</li>
  <li>The configuration of my application registration on the Azure Portal may be wrong.</li>
  </ul>
  
  <p>Any pointers on how to narrow this down or resolve this issue would be greatly appreciated!</p>