AccessDenied: Not authorized to perform sts:AssumeRoleWithWebIdentity
Asked Answered
S

3

25

I've looked around similar problems, but couldn't resolve my problem. I'm developing an web application where the user will authenticate using AWS Cognito's authentication. The sign up part is ok, but when I try to sign in, I'm getting the "not authorized" exception. I've already tried to attach custom policies to my IAM Role (authorizing sts:AssumeRoleWithWebIdentity), but didn't work.. Here is how the code is written right now:

        var cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
    onSuccess: function (result) {
        var sts = new AWS.STS({apiVersion: '2011-06-15'});

        var params = {
            RoleArn: 'arn:aws:iam::981601120657:role/Cognito_AliceAuth_Role', /* required */
            RoleSessionName: 'AliceUserSession', 
            WebIdentityToken: result.getIdToken().getJwtToken(), 
            Policy: '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRoleWithWebIdentity", "Resource": "*" } ] }'
        };

        sts.assumeRoleWithWebIdentity(params, function (err, data) {
            if (err)
                console.log(err, err.stack); // ** <-- ERROR HERE
            else
                console.log(data);           // successful response
        });

        //document.getElementById('authForm').submit();
    },
    onFailure: function (err) {
        alert(err);
    }

});

As you can see, I specified the policy in the code too, but I still get the "AccessDenied: Not authorized to perform sts:AssumeRoleWithWebIdentity" error. Please help me :/

EDIT:

Inside the "Cognito_AliceAuth_Role" I've created the role policies: AssumeRoleWithWebIdentityPolicy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Resource": "*"
        }
    ]
}

and: GetFederationTokenPolicy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:GetFederationToken",
            "Resource": "*"
        }
    ]
}

The trust relationship:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "cognito-identity.amazonaws.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:aud": "us-east-1:e4c1833d-a62b-402a-b995-1b2513b04c02"
        },
        "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "authenticated"
        }
      }
    }
  ]
}
Syphon answered 14/6, 2016 at 14:33 Comment(3)
How did attaching the policy to allow your IAM user to use sts:AssumeRoleWithWebIdentity not work?Cottony
I really don't know... :( I've updated the question adding more infoJoshua
When you try to authenticate using temporary credentials, what information do you provide?Cottony
M
8

Seems like you are using the Id token vended by Cognito user pools to call the assumeRoleWithWebIdentity.

You need to federate this token with Cognito identity first and you can use the Open Id connect token vended by Cognito identity to call assumeRoleWithWebIdentity.

You can directly call getCredentialsForIdentity as well using Enhanced flow.

See this document Accessing AWS services using an identity pool after sign-in to learn more about how to federate user pools token with Cognito identity.

Murguia answered 16/6, 2016 at 21:43 Comment(0)
O
3

Came across the same issue,

  • Create a user pool to serve as a user directory.
  • Register a user (User 1) in the user pool.
  • Create an identity pool and configure it to integrate with the user pool.
  • Create an IAM role that with the required permission. When creating the user use AssumeRoleWithWebIdentity option and add the identity pool ID in the wizard.
  • Create a group in the user pool and map the role we created and add some users to this group.
  • Now after authenticating the user via cognito configure the aws sdk with the jwt token.

AWS.config.region = "<YOUR_REGION>";

      AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId : '<YOUR_IDENTITY_POOL_ID>', 
        Logins : {
          // Change the key below according to the specific region your user pool is in.
          `cognito-idp.${AWS.config.region}.amazonaws.com/${data.UserPoolId}` : session.getIdToken().getJwtToken()
        }
      });

Reference Article - https://aws.amazon.com/blogs/developer/authentication-with-amazon-cognito-in-the-browser/

Overcritical answered 3/4, 2018 at 10:48 Comment(0)
O
0

To add to @Nirojan Selvanathan's answer, to do this with the v3 SDK and AWS Amplify you can use code similar to this

import { fromCognitoIdentityPool } from '@aws-sdk/credential-providers';
import { AssumeRoleWithWebIdentityCommand, STSClient } from '@aws-sdk/client-sts';

// get a user object using Amplify APIs (Auth.signIn and Auth.confirmSignIn in my case)
const user = getUserFromAmplifyLogin();

const credentials = fromCognitoIdentityPool({
  clientConfig: { region },
  identityPoolId,
  logins: {
    [`cognito-idp.${region}.amazonaws.com/${userPoolId}`]: user.signInUserSession.idToken.jwtToken,
  },
});

const stsClient = new STSClient({ region, credentials });
const request = new AssumeRoleWithWebIdentityCommand({...});
stsClient.send(request).then(...).catch(...);
Olszewski answered 27/9, 2023 at 8:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.