I am trying to get a session token for the given IAM in postman but not able to receive a token.
If I use boto3.client('sts'), I am able to get the token.
Use Case: I am trying to Invoke VPC Rest Endpoint from EC2 instance where ServiceNow mid-server instance is running. Since we have ServiceNow mid-server agent running on EC2 instance, I want to use IAM Role attached to EC2 to authenticate other VPC endpoints that are deployed in the same AWS account.
I have permission policy attached to IAM Role to allow Assume Role policy. If there any other approach, please suggest.
here HTML HTML response in postman. Postman redirecting to IAM Docs
client = boto3.client('sts')
response = client.assume_role(
RoleArn='arn:aws:iam::**************:role/ServiceNow-midserver-Role',
RoleSessionName='Session1',
DurationSeconds=3600
)
print(response)
anything wrong with postman request body or endpoint.
Authentication on postman is none.
To call AssumeRole from Postman (or curl etc.) as opposed to using a supported AWS SDK, you should follow the AssumeRole API documentation. You will also need to authenticate using AWS credentials.
Specifically, the request is an HTTP GET and parameters are passed as query strings, for example:
GET https://sts.amazonaws.com/
?Version=2011-06-15
&Action=AssumeRole
&RoleSessionName=stackoverflow-64706420
&RoleArn=arn:aws:iam::123456781234:role/myrole
&DurationSeconds=3600
Here's what this looks like in Postman:
And you will need to add AWS credentials so that your API request is signed correctly, for example:
Click 'Send' and the response will look something like this:
<AssumeRoleResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
<AssumeRoleResult>
<AssumedRoleUser>
<Arn>arn:aws:sts::123456781234:assumed-role/123456781234/stackoverflow-64706420</Arn>
<AssumedRoleId>ARO123EXAMPLE123:stackoverflow-64706420</AssumedRoleId>
</AssumedRoleUser>
<Credentials>
<AccessKeyId>ASIAIOSFODNN7EXAMPLE</AccessKeyId>
<SecretAccessKey>wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY</SecretAccessKey>
<SessionToken>
AQoDYXdzEPT//////////wEXAMPLEtc764bNrC9SAPBSM22wDOk4x4HIZ8j4FZTwdQW
LWsKWHGBuFqwAeMicRXmxfpSPfIeoIYRqTflfKD8YUuwthAx7mSEI/qkPpKPi/kMcGd
QrmGdeehM4IC1NtBmUpp2wUE8phUZampKsburEDy0KPkyQDYwT7WZ0wq5VSXDvp75YU
9HFvlRd8Tx6q6fE8YQcHNVXAkiY9q6d+xo0rKwT38xVqr7ZD0u0iPPkUL64lIZbqBAz
+scqKmlzm8FDrypNC9Yjc8fPOLn9FX9KSYvKTr4rvx3iSIlTJabIQwj2ICCR/oLxBA==
</SessionToken>
<Expiration>2020-12-09T13:34:41Z</Expiration>
</Credentials>
<PackedPolicySize>6</PackedPolicySize>
</AssumeRoleResult>
<ResponseMetadata>
<RequestId>c6104cbe-af31-11e0-8154-cbc7ccf896c7</RequestId>
</ResponseMetadata>
</AssumeRoleResponse>
You need to use credentials for an IAM user or an IAM role to call AssumeRole. boto3 must be getting credentials from the standard locations it look for (like ~/.aws/config) [ref:https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html]. May be you could try providing the AWS creds in Authorization tab in Postman selecting type as AWS Signature and then call assumeRole.
Related
I have created a basic lambda with lambda function url.
auth_type = aws_iam
allowed permissions for ec2 role in lambda resource based policy.
created a role to ec2 instance with full lambda permissions in the policy and attached it to the ec2 instance.
While invoking it from ec2 as below its getting forbidden error.
curl "https://<url-id>.lambda-url.<region>.on.aws"
I have tried with auth_type as none. Its working, but not working when i try with auth_type as aws_iam.
As explained in the docs, to invoke a lambda url with AWS_IAM, you have to sign your url request by constracting special URL which has your signature. Please check docs on how to construct a valid signature for URL requests.
I have an API Gateway endpoint with IAM authentication, no Custom Domain Names, no API Key, API is deployed to Prod and no AWS WAF enabled (TBMK) and VPC proxy integration request method.
I am calling this endpoint from a Lambda (with attached execute-api:Invoke permission to call the API), however I am getting a 403 error with message Forbidden. Notice that if I remove the IAM authentication method, the call from Lambda works fine.
I've already seen this and this SO questions + AWS Doc on the topic but I've already tried these solutions (as explained before).
Sample code for calling API Gateway inside Lambda:
final HttpURLConnection connection = (HttpURLConnection) new URL(postApiUrl).openConnection();
connection.setRequestMethod("POST");
final int responseCode = connection.getResponseCode();
//...
How I attach API Gateway ARN to Lambda role in CDK:
this.addToRolePolicy(
new PolicyStatement({
actions: [execute-api:Invoke],
effect: Effect.ALLOW,
resources: [postMethod.methodArn],
}),
);
You have set up IAM authentication for your API GW method, but your Lambda function code does not sign the request made to API GW. Note: Simply adding the execute-api:Invoke permission to the Lambda function execution role does not sign the request.
You need to use the AWS SigV4 signing process to add the authentication information which is then verified on the API GW end. This doc lists the steps involved which basically are:
Create a canonical request.
Use the canonical request and additional metadata to create a string for signing.
Derive a signing key from your AWS secret access key. Then use the signing key, and the string from the previous step, to create a signature.
Add the resulting signature to the HTTP request in a header or as a query string parameter.
Since you're using Java, this blog post also provides some sample code which you can refer to.
APIG has a authorizer cache, check this out.
https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-403-error-lambda-authorizer/
If you could have a read and perhaps elaborate a little I'll include the proper solution.
My users login to my application through a microservice that connects to cognito (the request is proxied via API gateway)
They get a session token.
Once logged in, they need to put some files to S3.
I want to give them temporary credentials using STS but to call sts.AssumeRoleWithWebIdentity I need a web identity token.
How can I get a web identity token with a session token as input?
I wrote a temporary lambda (node) that returns STS credentials upon logging with a username and password:
const cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider();
const cognitoidentity = new AWS.CognitoIdentity();
cognitoidentityserviceprovider.initiateAuth(...) //AuthFlow: 'USER_PASSWORD_AUTH'
cognitoidentity.getId(...)
cognitoidentity.getCredentialsForIdentity(...)
There can be some time between the login and the file upload and I don't want the user to submit user/password each time. There's no AuthFlow accepting a session token either.
I'm guessing the API Gateway could return something useful but I didn't find anything in the docs:
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html#context-variable-reference
A few checks first:
let cognito authenticated user to "masquerade" under an iam role, to do that we use trust relationships, for quick you can reuse the iam role that get assigned to your cognito identity pool.
grant that iam role a policy to access to s3 bucket
Once done:
Run cognitoidentity.getCredentialsForIdentity(...) again, it will go through sts first, thus you don't have to call sts assume role api. If successful, the response should have AccessKeyId, SecretKey and SessionToken. These are expiry aws creds that have access to s3 and will be gone after an hour (unless set). Use them as normal session authentication.
creds = new SessionAWSCredentials(AccessKeyId, SecretKey, SessionToken);
s3Request = CreateAmazonS3Client(creds);
I've managed to successfull login to the API gateway I've made via my iOS device and Cognito. The problem is I'd like to use postman to test the API calls then implement them on the phone. Currently, Postman cannot authenticate (despite AWS saying it can). No matter what I do I get a 401 error (visible in the screen-shots)
What I've tried
Downloaded the postman collection from AWS Api Gateway
Then imported it into postman, and switch the authentication to "AWS Signature"
And Here is a screen shot of the Postman Generated Header Info
If I understand correctly, you are trying to call an API Gateway endpoint that is behind the built-in Cognito Authoriser.
I think you've misunderstood how you call an Cognito Authorised API Gateway:
Authorise against Cognito to get an id_token
Call API Gateway with the Authorization header set to id_token
Renew id_token every hour
By enabling ADMIN_NO_SRP_AUTH you're allowing the first step (sign-in to Cognito) to be simplified so that you can more easily do it manually. (If you hadn't, then you would need to do SRP calculations).
One way to get the id_token is to use the aws cli (further ways are shown in the documentation):
aws cognito-idp admin-initiate-auth --user-pool-id='[USER_POOL_ID]' --client-id='[CLIENT_ID]' --auth-flow=ADMIN_NO_SRP_AUTH --auth-parameters="USERNAME=[USERNAME],PASSWORD=[PASSWORD]"
You can then use the result (AuthenticationResult.IdToken) as the Authorization header in Postman (no need for the AWS v4 signature- that is only for IAM authentication).
n.b. a much fuller explanation with images can be found here.
Here is what I finally did to fix postman auth issues
1) Turned off App Client Secret in the Cognito pool.
2) Ran aws --region us-east-1 cognito-idp admin-initiate-auth --cli-input-json file://gettoken.json
JSON file example
{
"UserPoolId": "us-east-1_**********",
"ClientId": "******************",
"AuthFlow": "ADMIN_NO_SRP_AUTH",
"AuthParameters": {
"USERNAME": "*********",
"PASSWORD": "***********"
}
}
3) Went to Postman > Authorization > Bearer Copied the idToken value into the token field and everything worked.
NOTE: For those wondering if not using a secret client key is safe. See this article.
I'm testing with AWS's Cognito. At this point, I can get back my IdToken, AccessToken, and RefreshToken like this:
$ aws cognito-idp admin-initiate-auth --user-pool-id us-east-1_XXXXXXXX --client-id XXXXXXXXXXXXXXXXXXXXXXX --auth-flow ADMIN_NO_SRP_AUTH --auth-parameters USERNAME=XXXXXXXXXXXXX,PASSWORD=XXXXXXXXXXXXX --region us-east-1
Then I tried the default web page (provided by Cognito) at a URL like this:
https://test-cognito.auth.us-east-1.amazoncognito.com/login?response_type=token&client_id=XXXXXXXXXXXXXXXXXXXXXX&redirect_uri=https://example.com
This URL will take me to a page where I have to authenticate and once the process is done it will take me back to my redirect_url with previously mentioned IDs appended:
https://example.com#id_token=XXXXX.XXXXXX.XXXXXX&access_token=XXXXXX.XXXXXXX.XXXXXXX&expires_in=3600&token_type=Bearer
But there's no sign of refresh_token! How can I get my refresh_token in this scenario?
I don't think that is possible at present. AWS clearly states that refresh token is only available if the flow type is Authorization Code Grant.
What you are trying is Implicit Grant. The responseType is set to token in your case. For Authorization Code Grant, set the grant type to code but that will also need you to store the client secret in the app.
Source- https://developer.amazon.com/docs/login-with-amazon/refresh-token.html.
For more info on grant types - https://alexbilbie.com/guide-to-oauth-2-grants/