GithubHelp home page GithubHelp logo

Comments (2)

jamey-taylor avatar jamey-taylor commented on August 24, 2024

Yes. I believe you are correct. This video and app is the ABSOLUTE BEST example I've found for marrying Cognito Federated Identities and Cognito User Pools, but it still has some gaps. But it has way fewer gaps that others (e.g. https://github.com/ionic-team/ionic2-starter-aws).

In the spacefinder app, methods that use Cognito User Pools Authorizer or the Custom Authorizer have no way to know if the user ID from Cognito Federated Identities goes with the claim.

From memory, here's what I did to fix it in my app:

User Pool

  1. Add custom field "custom:identityId".
  2. Make the field readable. Making it readable will make it part of jwt id tokens.

Custom Authorizer

  1. Near the end, JSON.stringify the decoded jwt and put it in the context, so that it's available to functions that use the Custom Authorizer. I put it in .context['custom:authorizer']

IAM

  1. The lambda execution role needs a couple new permissions.
    {
    "Action": [
    "cognito-idp:AdminGetUser",
    "cognito-idp:AdminUpdateUserAttributes"
    ],
    "Resource": [
    "arn:aws:cognito-idp:us-east-1:123456789012:userpool/us-east-1_xxxxxxxxx"
    ],
    "Effect": "Allow"
    }

New API method

  1. Create New api method for /user/ UPDATE
  2. This method uses AWS_IAM Authorizer and accepts an id or session token the request body. That means API Gateway will put the identityId in event.requestContext.identity.cognitoIdentityId, and you can trust that it's valid.
  3. API gateway did not validate the jwt in the body, so you have to do that yourself. You can borrowing all the code out of the custom authorizer in this sample. If the token valid, use cognito-idp.idp:AdminUpdateUserAttributes to store the identityId in a custom attribute.

Changes to existing API methods

  1. Now methods that use User Pools Authorizer can get the identityId from event.requestContext.authorizer.claims['custom:identityId']
  2. Methods that use the Custom Authorizer can get the identityId from (in my case) JSON.parse(event.requestContext.authorizer['custom:authorizer'])['custom:identityId'] (You can't put it the same place that the Cognito User Pools Authorizer uses because API Gateway will barf for no good reason if you put anything other than string, number, boolean in the context).
  3. But there's one more catch for 1 and 2 above. Right after you set the custom attribute, it won't be on subsequent reads of the token right away. So until it shows up, you need a fall-back to use cognito-idp:AdminGetUser to read it out of the custom attribute. I have no idea if that api call is rate-limited, but it should only be occurring for brand-new users and for a short time.

Changes to ionic app

  1. On login, if the 'custom:identityId' method is missing, call the new API method /users/ UPDATE to "link" the user.

from aws-serverless-auth-reference-app.

justonian avatar justonian commented on August 24, 2024

Hi there- To comment on this further, for the sake of time and due to this being a prototype reference app, we did send the userID through the payload without validating it. However, the much better way to do this, which would prevent spoofing is to have the effective IAM policy of the user (either from the IAM role assumed with Cognito Federated Identities or from the IAM policy returned by a custom authorizer with API Gateway) have only allow the user to invoke API operations on their particular user ID as a path parameter. For example, /users/userIdGuid and /users/userIdGuid/*. You can use either the identity ID from Cognito User Pools via an IAM policy variable as we have setup in our IAM policy, or if you're exclusively using Cognito User Pools with Custom Authorizers, use the unique subscriber ID of the user in the user pool.

Then, in the code of your function to do any modifications related to a user, pull the user ID out of the path parameter rather than the body, which is already being enforced via the execution policy so if the function code can even be invoked, you know that the path parameter sent through is that of the valid, actual user (unless an admin is calling operations and you've given them more broad permissions).

Hope this helps clarify a more secure method of validating the user ID. I think this is perhaps the most simple approach to solve this problem and prevent spoofing.

from aws-serverless-auth-reference-app.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.