‘JWT Signature is invalid’ with JWT AuthZ Grant

This topic has 6 replies, 4 voices, and was last updated 1 day, 9 hours ago by madhun.

  • Author
    Posts
  • #28368
     madhun
    Participant

    Hi,

    Getting error ‘JWT Signature is invalid’ with JWT Profiles OAuth 2.0 Authorization Grant

    We have a scenario where a user has already been authenticated by client and the identity needs to be propagated to an application secured with ForgeRock.

    While trying to get an access token from ForgeRock based on instructions at https://backstage.forgerock.com/docs/am/6.5/oauth2-guide/#oauth2-jwt-bearer, I get the error “JWT signature is invalid”.

    Details

    – ForgeRock Access Management 6.5.3 (Sep 2020)
    – JWT is generated using Nimbus JOSE library
    – Signed with a self-signed certificate
    – Certificate added to Client JWT Bearer Public Key field of the client profile in ForgeRock
    JWT Claims data passed (“sub”: <some-user>, “aud”: …/openam/oauth2/access_token, “iss”: <some-issuer>, etc.)
    – Added <some-issuer> in the ‘JWT Issuer’ field of a Trusted JWT Issuer
    – Added JWT Bearer and Client Credentials as Grant Types for the client

    – Being new to ForgeRock, I do not know how to configure JWKs URI nor JWK Set in the JWT Issuer Agent (see related questions below)! This could be the reason for the failure.

    Questions

    – The ‘assertion’ token passed to ForgeRock API validates fine by jwt.io with the same certificate added to ForgeRock client. This seems to indicate that token is fine.

    – The above ForgeRock documentation (#oauth2-jwt-bearer) has a curl example that matches everything used in my API invocation except data field redirect_uri’. Why is this redirect_uri required when it is a client-to-client interaction?

    – For authentication of clients using JWT Profiles (https://backstage.forgerock.com/docs/am/6.5/oauth2-guide/#client-auth-jwt), there is an instruction to enter the signing certificate as Client JWT Bearer Public Key. The same instruction is not present for #oauth2-jwt-bearer. I assume it is required for the latter too.

    – If ForgeRock can verify the signature using the configured public key, why is there a need to specify JWKs URI or JWK Set in the JWT Issuer Agent? [Note: Our same implementation for Oracle IDCS works fine with just the public key uploaded to the IDCS application. There is no concept of JWKs URI/JWK Set.]

    – It appears that the JWKs URI is a reference back to the calling client application, so that ForgeRock can call back and retrieve something (public key?). If so and if this is a different key from the one configured in ForgeRock, that would not have been used in signing the token anyway.

    Thanks,
    Madhu

    #28369
     Neil Madden
    Participant

    There are two techniques described in RFC 7523 – one is to use a JWT for client authentication, and the other is to use a JWT as an authorization grant.

    The Client JWT Bearer Public Key field is only used when using a JWT for client authentication. For the authorization grant, the public key to verify the signature comes from the Trust JWT Issuer – using either the JWK Set or JWKs URI fields.

    The are a couple of reasons for this split:
    – if we used the client public key, then any client that used a JWT for client auth (and is allowed to use the JWT Bearer grant) could get an access token for any user without any approval from that user. This can lead to security vulnerabilities.
    – you may want to reuse JWTs from the same issuer with multiple clients. For example if a central authority issues the JWTs or if you want to trust JWTs from an OIDC provider.

    Hope that helps!

    #28371
     Jatinder Singh
    Participant

    +1 above reply.

    Since you are using JWT Profile for OAuth 2.0 Authorization Grant and if your Issuer does not expose a JWK_URI, you can directly add the public key as a JWK in the keys array in the JWK SET field. To me that seem to be the issue why you may be running into JWT Signature is invalid for this particular grant.

    But if you want to authenticate a client using JWT token, that is a different use case as mentioned by Neil already. For that in addition to providing a Base64 encoded public key in the Client JWT Bearer Public Key field which you are doing already, you also have to set Public key selector field to x509.

    Hope this helps!

    #28372
     Scott Heger
    Participant

    One resource that helped me when testing/using the JWT Bearer Flow where I had a Trusted JWT Issuer that used a JWK Set was this: https://8gwifi.org/jwkconvertfunctions.jsp. It allows you to convert a PEM to a JWK so you can populate your JWK Set properly from the PEM of your public key. Just tossing this out there as it is related to the topic.

    #28375
     madhun
    Participant

    Summary: I am able to successfully get an access token using JWT Profiles OAuth 2.0 Authorization Grant. Thanks for all the pointers.

    @neil-madden
    Thanks for the explanation of the difference in mechanisms for client authentication and authorization grant.

    @jsingh
    1) I had to add something like the following in JWK Set field to make it work (apart from setting Public key selector to ‘JWKs’).

    {"keys":
      [
        {"kty":"RSA",
         "n": “xxxxxxxxxxxxxxxxxxxxxxxxxx”,
         "e":"AQAB",
         "alg":"RS256",
         "kid":"dx4cfabric"}
      ]
    }

    Per RFC7517 (https://tools.ietf.org/html/rfc7517), the following is another way to specify the key.

    The explanation says “… an example of a JWK with a RSA signing key represented both as an RSA public key and as an X.509 certificate using the “x5c” parameter …”.

    {"keys":
      [
        {"kty":"RSA",
         "use":"sig",
         "n": “xxxxxxxxxxxxxxxxxxxxxxxxxx”,
         "x5c": [“xxxxxxxxxxxxxxxxxxxxxxxxxx”],
         "e":"AQAB",
         "alg":"RS256",
         "kid":"dx4cfabric"}
      ]
    }

    I used the above example to get an access token after removing the attribute “n” (the line “n”: “xxxxxxxxxxxxxxxxxxxxxxxxxx”,) keeping only “x5c”, but I got back the original error “JWT signature is invalid”.

    If the standard calls it representing the same signing key in 2 ways, should it not work with either one of “n” and “x5c” being part of the key? Does ForgeRock always expect “n”?

    Reason for my question – I don’t know of a standard way to convert PEM to JWK without relying on a tool such as the one pointed to by Scott or any other third-party one. We already have the x509 certificate, so it would be nice to be able to use that directly.

    2) By the way, client authentication worked for me with just the public key in Client JWT Bearer Public Key, even though Public key selector was set to ‘JWKs_URI’ (probably the default). In any case, it is as well because I need to set it to ‘JWKs’ for the authorization grant flow (we have both flows).

    @shegergmail-com
    Thanks for the online link that converts PEM to JWK. That helped.

    #28376
     Jatinder Singh
    Participant

    @madhun Since a JWK represents a cryptographic key, a key can utilize any given cryptographic algorithm. The decision on what parameters to include for a given algorithm is part of the JWA specification. For example, the parameter n is not needed for Elliptic Curve based algorithm but required for RSA.

    To answer your question on what parameters are viable in your scenario – it depends upon your cryptographic key. I would suggest not constructing these keys manually but use an underlying library to ensure the output is correct and per the specification.

    #28379
     madhun
    Participant

    Thanks, @jsingh. I will look into using some library to derive JWK from our public key.

Viewing 7 posts - 1 through 7 (of 7 total)

You must be logged in to reply to this topic.

©2020 ForgeRock - we provide an identity and access platform to secure every online relationship for the enterprise market, educational sector and even entire countries. Click to view our privacy policy and terms of use.

Log in with your credentials

Forgot your details?