I have a connected app that I would like to connect to using a JWT flow using a bearer token.
Using anonymous Apex I have:
// The consumer key for a connected app of mine
String iss = '<MY CONSUMER KEY>';
String aud = 'https://test.salesforce.com';
String sub = 'my_user_name';
Long exp = DateTime.now().addMinutes(5).getTime();
Auth.JWT jwt = new Auth.JWT();
jwt.setAud(aud);
jwt.setIss(iss);
jwt.setSub(sub);
jwt.setValidityLength(Integer.valueof(exp));
// Storing the certificate in Salesforce is a requirement for using the JWS class
// I just created a certificate under 'Certificate and Key Management' and using that below (jini)
Auth.JWS jws = new Auth.JWS(jwt, 'jini');
String tokenEndpoint = 'https://my.sandbox.my.salesforce.com/services/oauth2/token';
Auth.JWTBearerTokenExchange bearer = new Auth.JWTBearerTokenExchange(tokenEndpoint, jws);
String accessToken = bearer.getAccessToken();
system.debug(accessToken);
When I execute it, I get:
18:29:26:041 EXCEPTION_THROWN [33]|Auth.JWTBearerTokenExchange.JWTBearerTokenExchangeException: Error 400: {"error":"invalid_grant","error_description":"expired authorization code"}
My user belongs to one of the pre-authorized profiles for the connected app. I have also added my sandbox url to the remote site settings although that may not be needed.
What am I doing wrong? I think it may be due to the certificate but I am not sure.