AWS: Restrict Cognito Authorized User to specific Lambda Functions

后端 未结 1 498
一生所求
一生所求 2021-01-16 13:27

I\'m working with AWS and I\'ve the following setup: UserPool; API Gateway, Lambda Functions

The api gateway is using a UserPool authorizer to protect the lambda fun

相关标签:
1条回答
  • 2021-01-16 14:12

    So I've found a solution to my problem. Here is the summary of my experiences:

    • Cognito Authorizer is more like a yes/no authorizer (authenticated or not; user groups are not evaluated)
    • Therefore I went with AWS IAM Authorizer in the API Gateway, which will evaluate the user group roles
    • Instead of a JWT the AWS signature v4 authorization has to be passed (there is a plugin for postman and several packages on npm)
    • Since I am using an API Gateway I had to change the role policy resources to execute-api:Invoke

    In detail:

    UserRole:

    {
      "Version": "2012-10-17",
      "Statement": [
        "Action": [
          "lambda:InvokeFunction",
          "lambda:InvokeAsync"
        ],
       "Resource": [
         "arn:aws:execute-api:region:accountid:api-id/stage/GET/items
        ],
        "Effect": "Allow"
      ]
    }
    

    AdminRole:

    {
      "Version": "2012-10-17",
      "Statement": [
        "Action": [
          "lambda:InvokeFunction",
          "lambda:InvokeAsync"
        ],
       "Resource": [
         "arn:aws:execute-api:region:accountid:api-id/stage/GET/items
         "arn:aws:execute-api:region:accountid:api-id/stage/*/users
        ],
        "Effect": "Allow"
      ]
    }
    

    Instead of passing the ID Token into the Authorization header, I had to use Postman AWS Signature, which requires at least an AccessKey and a SecretKey. Those two can be retrieved when I sign in my user using the aws-sdk. aws-sdk-js with TypeScript as example:

    import { CognitoUserPool, CognitoUser, AuthenticationDetails } from 'amazon-cognito-identity-js';
    
    const userPool = new CognitoUserPool({
      UserPoolId: 'my pool id',
      ClientId: 'my client id'
    });
    
    function signIn(username: string, password: string) {
      const authData = {
        Username: username,
        Password: password,
      };
    
      const authDetails = new AuthenticationDetails(authData);
      const userData = {
        Username: username,
        Pool: userPool,
      };
    
      const cognitoUser = new CognitoUser(userData);
      cognitoUser.authenticateUser(authDetails, {
        onSuccess: (result) => {
          const cognitoIdpKey = `cognito-idp.${region}.amazonaws.com/${userPool.getUserPoolId()}`;
    
          const credentials = new AWS.CognitoIdentityCredentials({
            IdentityPoolId: 'identity pool id,
            Logins: {
              [cognitoIdpKey]: result.getIdToken().getJwtToken(),
            }
          });
          AWS.config.update({
            credentials,
          });
    
          credentials.refreshPromise()
            .then(() => {
              console.log('Success refresh. Required data:', (credentials as any).data.Credentials);
            })
            .catch(err => console.error('credentials refresh', err));
        }
      });
    }
    
    0 讨论(0)
提交回复
热议问题