You need to sign in to do that
Don't have an account?
Helen He 7
InvalidJwtException while validating JWT token generated in salesforce
Hi All,
We are going to use Salesforce as IdP and Weblogic as SP which hosts our existing java web apps, thinking about OAuth 2.0 JWT Bearer Token Flow for the SSO.
Basically user logs into our customized community, clicks a link which redirects user to external web apps via http request, a bearer token with extra claims is set in the authorization header. Our java web doesn’t need to talk back to salesforce, it just needs to validate the JWT token for the authentication.
I creates a connected app with digital signature, create JWT token with extra claims using apex Auth.JWT, then I verify the JWT using jose4j in java, but get the following error while validating the JWT in java, I use https://login.salesforce.com/id/keys as the key resolver since I use my developer account to create the JWT token
org.jose4j.jwt.consumer.InvalidJwtException: Unable to process JOSE object (cause: org.jose4j.lang.UnresolvableKeyException: Unable to find a suitable verification key for JWS
Any input is appreciated.
Here are links I followed for implementation
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_class_Auth_JWTBearerTokenExchange.htm
https://help.salesforce.com/articleView?id=remoteaccess_asset_token_using_validating.htm&type=5
And here is my codes
Apex code for generating JWT
Generated JWT looks like this:
Java code for validation
We are going to use Salesforce as IdP and Weblogic as SP which hosts our existing java web apps, thinking about OAuth 2.0 JWT Bearer Token Flow for the SSO.
Basically user logs into our customized community, clicks a link which redirects user to external web apps via http request, a bearer token with extra claims is set in the authorization header. Our java web doesn’t need to talk back to salesforce, it just needs to validate the JWT token for the authentication.
I creates a connected app with digital signature, create JWT token with extra claims using apex Auth.JWT, then I verify the JWT using jose4j in java, but get the following error while validating the JWT in java, I use https://login.salesforce.com/id/keys as the key resolver since I use my developer account to create the JWT token
org.jose4j.jwt.consumer.InvalidJwtException: Unable to process JOSE object (cause: org.jose4j.lang.UnresolvableKeyException: Unable to find a suitable verification key for JWS
Any input is appreciated.
Here are links I followed for implementation
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_class_Auth_JWTBearerTokenExchange.htm
https://help.salesforce.com/articleView?id=remoteaccess_asset_token_using_validating.htm&type=5
And here is my codes
Apex code for generating JWT
Auth.JWT jwt = new Auth.JWT(); jwt.setSub('XX@XXX.XXX'); jwt.setAud('https://login.salesforce.com'); jwt.setIss('3MVG9KsVczVNcM8y.FPNyZ.BU9I1hnzFYR1VBtqxIyA2mJoJ8zsHwzEE8GkytJwXWhSTwulBu14ecCMp3XV2q'); //Additional claims to set scope Map<String, Object> claims = new Map<String, Object>(); claims.put('scope', 'scope name'); jwt.setAdditionalClaims(claims); //Create the object that signs the JWT bearer token Auth.JWS jws = new Auth.JWS(jwt, 'SelfSignedCert_02Feb2019_210623'); //Get the resulting JWS in case debugging is required String token = jws.getCompactSerialization();
Generated JWT looks like this:
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlNlbGZTaWduZWRDZXJ0XzAyRmViMjAxOV8yMTA2MjMifQ.eyJpc3MiOiIzTVZHOUtzVmN6Vk5jTTh5LkZQTnlaLkJVOUkxaG56RllSMVZCdHF4SXlBMm1Kb0o4enNId3pFRThHa3l0SndYV2hTVHd1bEJ1MTRlY0NNcDNYVjJxIiwic3ViIjoiemhlQG5ibWUub3JnIiwiYXVkIjoiaHR0cHM6Ly9sb2dpbi5zYWxlc2ZvcmNlLmNvbSIsImlhdCI6MTU1NTYwMzc4NywibmJmIjoxNTU1NjAzNzU3LCJleHAiOjE1NTU2MDQwODcsImp0aSI6IjJjZjg1ZTE5LTE1MjMtNDgyNS04MjEyLTcwNzQ2NTcwNDk1NSIsInNjb3BlIjoic2NvcGUgbmFtZSJ9.WU3QTDA5ixc1dG5fTYtdHKbkNoTglFYfu9XznzeqEAq6w44db
Java code for validation
final String ISSUER = "https://login.salesforce.com"; final String KEY_ENDPOINT = ISSUER + "/id/keys"; final String AUDIENCE = "https://login.salesforce.com"; boolean isValidAssetToken = false; String assetToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlNlbGZTaWduZWRDZXJ0XzAyRmViMjAxOV8yMTA2MjMifQ.eyJpc3MiOiIzTVZHOUtzVmN6Vk5jTTh5LkZQTnlaLkJVOUkxaG56RllSMVZCdHF4SXlBMm1Kb0o4enNId3pFRThHa3l0SndYV2hTVHd1bEJ1MTRlY0NNcDNYVjJxIiwic3ViIjoiemhlQG5ibWUub3JnIiwiYXVkIjoiaHR0cHM6Ly9sb2dpbi5zYWxlc2ZvcmNlLmNvbSIsImlhdCI6MTU1NTYwMzc4NywibmJmIjoxNTU1NjAzNzU3LCJleHAiOjE1NTU2MDQwODcsImp0aSI6IjJjZjg1ZTE5LTE1MjMtNDgyNS04MjEyLTcwNzQ2NTcwNDk1NSIsInNjb3BlIjoic2NvcGUgbmFtZSJ9.WU3QTDA5ixc1dG5fTYtdHKbkNoTglFYfu9XznzeqEAq6w44db"; // The HttpsJwksVerificationKeyResolver uses JWKs obtained from the HttpsJwks and // selects the most appropriate one to use for verification based on the Key ID and other factors // provided in the header of the JWS/JWT. HttpsJwks httpsJkws = new HttpsJwks(KEY_ENDPOINT); HttpsJwksVerificationKeyResolver httpsJwksKeyResolver = new HttpsJwksVerificationKeyResolver(httpsJkws); // The JwtConsumer establishes the rules for Validation of our asset token. JwtConsumer jwtConsumer = new JwtConsumerBuilder() .setVerificationKeyResolver(httpsJwksKeyResolver) .setRequireExpirationTime() // The JWT must have an expiration time. .setAllowedClockSkewInSeconds(30) // Allow some leeway in validating time-based claims to account for clock skew. .setExpectedIssuer(ISSUER) // Entity that the asset token must be issued by. .setExpectedAudience(AUDIENCE) // Entity that the asset token is intended for. .build(); // Create the JwtConsumer instance. try { // Validate the JWT and process it to the Claims. JwtClaims jwtClaims = jwtConsumer.processToClaims(assetToken); isValidAssetToken = true; } catch (InvalidJwtException e) { // InvalidJwtException thrown if the asset token failed processing or validation. System.out.println("Invalid Asset Token: " + e); }
Jefferson Jones
In the JWT bearer token exchange sequence, the client generates if the asset token failed processing or validation mybkexperience (https://mybkexperience.me).