1

We have suddenly started getting below error while decoding JWT generated by AWS Cognito. Spring Security JWT

{
    "error": "access_denied",
    "error_description": "Invalid token does not contain resource id (oauth2-resource)"
}

We re using Spring boot version : 2.0.3.RELEASE

This is more specific to tokens generated by AWS Cognito.And why it stopped working all of sudden with no changes in code base/spring lib or infra


Latest update : Seems AWS has reverted thr change(addition of 'aud claim) below decoded JWT tells the story

Todays(16 Oct 2019) JWT

 {
    "sub": "XXXXXXXXXXXX-6a8dd388a720",
    "token_use": "access",
    "scope": "XXXXXXXXXXXX",
    "auth_time": 1571227222,
    "iss": "YYYYYYYYYYYYYYYY",
    "exp": 1571230822,
    "iat": 1571227222,
    "version": 2,
    "jti": "XXXXXXXXXXXXXYYYYYYYYYYYYY",
    "client_id": "someclient_id",
    "username": "someusername"
     }

Yesterday we were getting :

  {
  "sub": "xxxxxxxxxxxxx",
  **"aud": "sameasclientid",**
  "token_use": "access",
  "scope": "somescope",
  "auth_time": 1571132619,
  "iss": "rrrrrrrrrrrrrrrrrrrrr",
  "exp": 1571136219,
  "iat": 1571132619,
  "version": 2,
  "jti": "xxxxxxxxxxxxxxxxx",
  "client_id": "sameasclientid",
  "username": "someusername"
 }
Mahesh_Loya
  • 2,743
  • 3
  • 16
  • 28
  • Possible duplicate of [Why is my token being rejected? What is a resource ID? "Invalid token does not contain resource id (oauth2-resource)"](https://stackoverflow.com/questions/47996344/why-is-my-token-being-rejected-what-is-a-resource-id-invalid-token-does-not-c) – Carlos López Marí Oct 15 '19 at 11:51

2 Answers2

-1

We got this resolved using the SO link here.

It seems the token generated by AWS Cognito is now having a new claim aud added to the token. Spring OAuth expects aud claim in JWT token to be oauth2-resource by default.

The fix was to add the aud in the JWT token in the Spring Resource Server configuration whose value is the client_id.

  @Value("${security.oauth2.resource.id:}")
  private String jwtAudResourceId;

  @Override
  public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
    resources.resourceId(jwtAudResourceId);
  }

For information about JWT claims in cognito token can be found here.


Updates


Seems AWS has reverted the change where they added 'aud' claim in JWT token. We are no more receiving the 'aud' claim in JWT

Decoded JWT we were getting yesterday(15 Oct 2019)

{
  "sub": "XXXXXXXXXXXXXXXXX",
  "aud": "SAME_AS_CLIENT_ID",
  "token_use": "access",
  "scope": "SOMESCOPE",
  "auth_time": 1571132619,
  "iss": "SOME_ISSUER",
  "exp": 1571136219,
  "iat": 1571132619,
  "version": 2,
  "jti": "8XXXXXXXXXXXXXXXX",
  "client_id": "SAME_AS_CLIENT_ID",
  "username": "SOME_USERNAME"
}

Decoded JWT we are getting today(16 Oct 2019

{
  "sub": "XXXXXXXXXXXXXXXXX",
  "token_use": "access",
  "scope": "SOMESCOPE",
  "auth_time": 1571227222,
  "iss": "SOME_ISSUER",
  "exp": 1571230822,
  "iat": 1571227222,
  "version": 2,
  "jti": "8XXXXXXXXXXXXXXXX",
  "client_id": "SAME_AS_CLIENT_ID",
  "username": "SOME_USERNAME"
}

So now it should work even if we DO NOT configure it as below.OR remove below snippet from configuration class :

@Override
public void configure(ResourceServerSecurityConfigurer config) throws 
Exception {
    config.resourceId(null).tokenServices(tokenServices());
}
Mahesh_Loya
  • 2,743
  • 3
  • 16
  • 28
  • 1
    This is not correct, one token can contain multiple resource id's separated by space. Please refer the documentation of Oauth2 standards. "aud" param's value set same as clientId is a wrong implementation by Coginto, that is why maybe they have reverted their change today. Instead set the resourceId to 'null' so that spring security by-passes the check. – chandramohan Oct 16 '19 at 10:22
  • The answer was a workaround.As we already raised a ticket with AWS.Moreover AWS,Cognito doesnt implement OAuth completely ,it seems they did some tailor made solution.Whether it is correct or not depends on the usefulness of the answer. – Mahesh_Loya Oct 16 '19 at 11:48
-1

I faced similar issue, in my case I don't need to the validate the "aud" param which is added in the JWT claim.

It was not a correct implementation from AWS Cognito, meaning, "aud" should contain the resource-ids of the resource servers against which the carrying token will be used, but Cognito was just copying the same value as "clientId". In our case there are multiple client's which can call one resource server, according to Coginto's implementation resource server needs to know the list of clientId's, which is wrong from Oauth2 standards.

To know more on this please visit, https://www.rfc-editor.org/rfc/rfc7523, it says

The JWT MUST contain an "aud" (audience) claim containing a value that identifies the authorization server as an intended audience. The token endpoint URL of the authorization server MAY be used as a value for an "aud" element to identify the authorization server as an intended audience of the JWT. The authorization server MUST reject any JWT that does not contain its own identity as the intended audience. In the absence of an application profile specifying otherwise, compliant applications MUST compare the audience values using the Simple String Comparison method defined in Section 6.2.1 of RFC 3986 [RFC3986]. As noted in Section 5, the precise strings to be used as the audience for a given authorization server must be configured out of band by the authorization server and the issuer of the JWT.

So if you don't need to verify the "aud" parameter, set the resourceId of resource server to null (default value 'oauth2-resource') as shown below.

@Override
public void configure(ResourceServerSecurityConfigurer config) throws Exception {
    config.resourceId(null).tokenServices(tokenServices());
}

Spring security ignores the "aud" parameter if the resource server's resourceId is null.

Community
  • 1
  • 1
chandramohan
  • 558
  • 5
  • 19