Search code examples
javaamazon-web-servicesauthenticationamazon-cognitologin-with-amazon

Login with amazon and access aws resources like S3, EC2 etc


I have a web application that enables a user to manage AWS resources easily like start an Ec2 instance using GUI. Different users can use this web application. I have implemented my own user management. It is possible that some users don't want to create an account to my web-app and store their credentials to make requests to AWS resources. It may not be secure for them. So, I want to build a mechanism using following flow.

  1. User login to my web-app using login with amazon
  2. Login with amazon will provide an access token to me
  3. Fetch temporary credentials using this token
  4. Use these credentials for future request to AWs resources

In this way, there will be no permanent credentials stored in my web-app.

I'm using java for my backend services. So is there any AWS APi's to do so?

I have tried the following code:

 val client = new AmazonCognitoIdentityClient(new AnonymousAWSCredentials())
    val idRequest = new GetIdRequest();
   idRequest.setAccountId(account-id);
 idRequest.setIdentityPoolId("us-east-1:xxxx");
   // If you are authenticating your users through an identity provider
    // then you can set the Map of tokens in the request
 val logins = new HashMap[String, String]()
  providerTokens+=("www.amazon.com"->"Atza|IwE-xxxxxxxxxxxxxxxxxxx")

  idRequest.setLogins(logins);

  val idResp = client.getId(idRequest)

 val identityId = idResp.getIdentityId()


    // Create the request object
    val tokenRequest = new GetOpenIdTokenRequest();
    tokenRequest.setIdentityId("us-east-1:xxxxxx");

//
    val tokenResp = client.getOpenIdToken(tokenRequest);
//     get the OpenID token from the response
    val openIdToken = tokenResp.getToken()

//     you can now create a set of temporary, limited-privilege credentials to access
//     your AWS resources through the Security Token Service utilizing the OpenID
//     token returned by the previous API call. The IAM Role ARN passed to this call
//     will be applied to the temporary credentials returned


    val stsClient = new AWSSecurityTokenServiceClient(new AnonymousAWSCredentials());
    val stsReq = new AssumeRoleWithWebIdentityRequest();
    stsReq.setRoleArn("arn:aws:iam::account-id:role/Cognito_Auth_Role");
    stsReq.setWebIdentityToken(openIdToken);
    stsReq.setRoleSessionName("AppTestSession");
    val stsResp = stsClient.assumeRoleWithWebIdentity(stsReq);
    val stsCredentials = stsResp.getCredentials();

i get the following error:

Access to Identity 'us-east-1:xxxxxxxxxxxxxxxx' is forbidden. (Service: AmazonCognitoIdentity; Status Code: 400; Error Code: NotAuthorizedException

Following is the Cognito_Auth_Role role policy in IAM roles:

{
  "Version": "2012-10-17",
  "Statement":[{
      "Effect":"Allow",
      "Action":"cognito-sync:*",
      "Resource":["arn:aws:cognito-sync:us-east-1:xxxxxxx:identitypool/${cognito-identity.amazonaws.com:aud}/identity/${cognito-identity.amazonaws.com:sub}/*"]
      }]
  }

And here is the trust relationships for this role:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Federated": "cognito-identity.amazonaws.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:aud": "us-east-1:xxxxx"
        },
        "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "www.amazon.com"
        }
      }
    }
  ]
}

Please point me out, what is wrong here?

Thanks


Solution

  • You can use AWS Cognito to handle most of the plumbing, or you can connect your own OpenId Identity Provider or a provider service you subscribe to.

    Here's the docs for Identity and Access Management (IAM): https://aws.amazon.com/documentation/iam/

    Or you can have them do some of the plumbing for you with Cognito: http://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html

    While it looks like that's only for mobile, they have docs on using their JavaScript SDK in the browser: http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/browser-intro.html