OAUTH Password Grant Type with Cognito

1

Hi. I have customers that need to make authenticated AppSync requests from a headless server. This is a machine-to-machine API call where when certain events happen on one site, calls to my service (implemented with AppSync) need to occur. There is a custom user attribute App Sync accesses for scoping queries and mutations.

I am able to retrieve an AccessToken using this call: curl -X POST --data @aws-auth-data.json -H 'X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth' -H 'Content-Type: application/x-amz-json-1.1' https://cognito-idp.us-east-1.amazonaws.com/us-east-1_ad***dfs

but that syntax requires using AWS proprietary headers and endpoints. Instead, I'd like to use my custom domain hosted by cognito and the standard OAUTH password flow. It should look like this: curl -X POST https://auth.mydomain.com/token -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=client_credentials&username=myname&password=mypassword&client_id=4at70aijtkr7sdX9hjt4d81"

When I do this, I get a response: {"error":"invalid_scope"}

Has anyone had success with this grant type using Cognito? If the solution is to generate App Clients instead of Cognito Identities, can you suggest how to associate the custom user attributes that App Sync needs for authorization?

Thanks!

1 Answer
-1

Hi,

I understand that you're trying to use client credentials grant type, but you're facing the {"error":"invalid_scope"} error message while trying to make the request to fetch the access_token.

Details on how to use client credentials grant type are outlined in the documentation below:

  1. https://aws.amazon.com/blogs/mobile/understanding-amazon-cognito-user-pool-oauth-2-0-grants/

The client credentials grant is intended to provide credentials to an application in order to authorize machine-to-machine requests and please note that in order to use the client credentials grant, the corresponding user pool app client must have an associated app client secret.

The app makes a POST request to https://AUTH_DOMAIN/oauth2/token, with the following parameters:

grant_type – Set to “client_credentials” for this grant type. client_id – The ID for the desired user pool app client. scope – A space-separated list of scopes to request for the generated access token.

The POST request is made to the token endpoint as you are already aware:

  1. TOKEN endpoint - https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html
  2. https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint

The AUTH_DOMAIN represents the user pool’s configured domain. And so, if you are using a custom domain for the user pool ensure to hit the token endpoint "https://AUTH_DOMAIN/oauth2/token" using "/oauth2/token" to gets the user's tokens.

In order to indicate that the app is authorized to make the request, the Authorization header for this request is set as “Basic BASE64(CLIENT_ID:CLIENT_SECRET)“, where BASE64(CLIENT_ID:CLIENT_SECRET) is the base64 representation of the app client ID and app client secret, concatenated with a colon.

Here's a sample request to exchange client credentials for an access token:

                       POST https://AUTH_DOMAIN/oauth2/token >
                       Content-Type='application/x-www-form-urlencoded'&
                       Authorization=Basic aSdxdexample3456uedj
                       
                       grant_type=client_credentials&
                       scope={resourceServerIdentifier1}/{scope1} {resourceServerIdentifier2}/{scope2}

You will need to include the "scope" which can be a combination of any custom scopes associated with a client. "Any scope requested must be pre-associated with the client or it will be ignored at runtime. If the client doesn't request any scopes, the authentication server uses all custom scopes associated with the client." (Reference document 2)

Please refer to the following documentation for more information on managing resource servers and custom scopes:

  1. Defining resource servers for your user pool - https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-define-resource-servers.html

The access token will contain claims about the authenticated user, a list of the user's groups, and a list of scopes. You can use the access token to grant your user access to add, change, or delete user attributes.

  1. Using the access token - Access token payload - https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-the-access-token.html#user-pool-access-token-payload

The GetUser call should be able to pull up user attributes using the access token. Similarly, the UpdateUserAttributes call allows a user to update a specific attribute, one at a time.

  1. GetUser - https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_GetUser.html
  2. UpdateUserAttributes - https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserAttributes.html

Let us know if you need any information further!

AWS
SUPPORT ENGINEER
answered 2 years ago
  • Thank you @Sumukhi_P.

    You lost me after step 4. "The access token will contain claims about the authenticated user..."

    In this case, the access token I retrieved was one associated with the app client with the credentials being that client's key and secret. At what point am I associating a user with user attributes?

  • I think something was crossed. You indicated client_credentials but had a username and password. that would be the "password" grant type which cognito does not seem to support.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions