Search code examples
amazon-web-servicesauthenticationamazon-cognito

AWS cognito returning - 'Invalid Login Token. Not a Cognito Token'


I am able to successfully retrieve an identity token for my Custom Authentication Provider (Developer Authentication). This is implemented using the Cognito devauth demo servlet.

This token is returned to a browser running AWS JS SDK. When I make a call to getCredentialsForIdentiy, I receive the 'Invalid Login Token' error.

POST https://cognito-identity.us-west-2.amazonaws.com/ 400 (Bad Request)
app.js:150 Error: Invalid login token. Not a Cognito token.
    at constructor.a (aws-sdk-2.58.0.min.js:41)
    at constructor.callListeners (aws-sdk-2.58.0.min.js:41)
    at constructor.emit (aws-sdk-2.58.0.min.js:41)
    at constructor.emitEvent (aws-sdk-2.58.0.min.js:41)
    at constructor.e (aws-sdk-2.58.0.min.js:41)
    at i.runTo (aws-sdk-2.58.0.min.js:43)
    at aws-sdk-2.58.0.min.js:43
    at constructor.<anonymous> (aws-sdk-2.58.0.min.js:41)
    at constructor.<anonymous> (aws-sdk-2.58.0.min.js:41)
    at constructor.callListeners (aws-sdk-2.58.0.min.js:41) "NotAuthorizedException: Invalid login token. Not a Cognito token.
    at constructor.a (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:41:615)
    at constructor.callListeners (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:41:30513)
    at constructor.emit (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:41:30224)
    at constructor.emitEvent (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:41:16590)
    at constructor.e (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:41:12285)
    at i.runTo (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:43:7277)
    at https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:43:7482
    at constructor.<anonymous> (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:41:12495)
    at constructor.<anonymous> (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:41:16645)
    at constructor.callListeners (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:41:30619)"

I am passing to getCredentialsForIdentity the following params.

identityId: <returned from servlet in region:guid format>
customRoleArn: <that maps to authenticated role>
Logins: <cognito-identity.amazonaws.com = token returned by congito>

I notice that new congnito identity was created by using id browser. So, the token interaction with the servlet seems correct. But the token is being rejected.

What am I missing here? How can I troubleshoot it further?

Edit: Browser client: javascript sdk, version 2.58. Essentially writing a JS client to this demo . The modifications is only to get token as part of login call itself. The generated token corresponds to a role that only has IOT client access. (I wonder if that policy needs to expand). Eventually the users will be validated against an internal ID store instead of this demo.

Edit 2: Instead of calling getCredentialsForIdentiy against Cognito Service, I invoked assumeRoleWithWebIdentity against STS and that worked. The use of Basic Flow instead of Enhanced flow here. . Really not sure why enhanced flow did not work but will take the basic flow approach for now.


Solution

  • So, the AWS documentation here is either inaccurate or documents an inefficient scenario.

    Using JavaScript Cognito API, my Developer Provider returned token could not be used with GetCredentialsForIdentity against Cognito API. (this is what prompted me to ask this question).

    However, I can use the same token against STS API and invoke AssumeRoleWithWebIdentity which essentially returns the same response parameters as GetCredentialsForIdentity above. This is the approach I took.

    Basic Auth Flow documentation in the first link seems inaccurate. Because it lists 'get credentials' and 'assume role' as required steps but only one is actually needed. Also, from a browser, this is an API call out to an Amazon service. So using Enhanced Flow instead of Basic does not seem like an advantage if it worked.