1
votes

I am Creating a URL that Enables Federated Users to Access the AWS Management Console by sts:AssumeRole with below reference by using python Boto3 AWS SDK -

https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html#STSConsoleLink_programPython

I can successfully assume a role via AWS CLI. But, I do not understand at all why when I use the Boto library and calling the python script by PHP and shell_exe I receive the following error:

botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the AssumeRole operation: User arn:aws:iam::xxx:user/admin is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::xxx/(role-name)

Here admin user has full administrative access, and the same script running successfully and giving login link by CLI :-

aws sts assume-role --role-arn arn:aws:iam::123456789012:role/role-name --role-session-name "RoleSession1"

This is the python sample:

#!/usr/bin/python35
import urllib, json
import requests 
import boto3 
import urllib.parse
import sys
import cgi
import json

sts_connection = boto3.client('sts',aws_access_key_id='my_access_key',aws_secret_access_key='my_secret_key')
assumed_role_object = sts_connection.assume_role(
    RoleArn=my_role_arn,
    RoleSessionName="AssumeRoleSession"
)    

json_string_with_temp_credentials = '{'
json_string_with_temp_credentials += '"sessionId":"' + assumed_role_object.get('Credentials').get('AccessKeyId') + '",'
json_string_with_temp_credentials += '"sessionKey":"' + assumed_role_object.get('Credentials').get('SecretAccessKey') + '",'
json_string_with_temp_credentials += '"sessionToken":"' + assumed_role_object.get('Credentials').get('SessionToken') + '"'
json_string_with_temp_credentials += '}'

request_parameters = "?Action=getSigninToken"
request_parameters += "&SessionDuration=1800"
request_parameters += "&Session=" + urllib.parse.quote(json_string_with_temp_credentials)
request_url = "https://signin.aws.amazon.com/federation" + request_parameters
r = requests.get(request_url)

signin_token = json.loads(r.text)


request_parameters = "?Action=login" 
request_parameters += "&Issuer=www.whizlabs.com" 
request_parameters += "&Destination=" + urllib.parse.quote("https://console.aws.amazon.com/")
request_parameters += "&SigninToken=" + signin_token["SigninToken"]
request_url = "https://signin.aws.amazon.com/federation" + request_parameters

print (request_url)

Problem with calling the same script by webserver using PHP shell_exec as follows -:

$output = shell_exec("python3 get_link.py arn=".$arn." 2>&1");

I do not think that the problem is with IAM roles and policies; if it was, AWS CLI would not connect as well.

Any suggestion?

2
The error clearly states the problem. Please show the permissions associated with the admin IAM user. Are the User and the Role in the same AWS Account? Also, when you run from the AWS CLI you are using credentials from the credentials file, yet in your code you have hard-coded credentials. It is recommended to never hard-code credentials in source code. If you leave them out, boto3 will use the credentials file, too. (It is quite likely that your app is using different credentials to the AWS CLI.) - John Rotenstein
Thanks John for sharing this, My admin IAM user has full administrative access. I am using the same credentials in boto3 as aws cli . How can I configure it for boto3 credentials file, can you please share some tutorial or something from where I can get hepl. - Rahul Gaikwad
If your aws command works, then you already have a credentials file that works. Your code (if run as the same user on the same computer) will automatically find it. So, there is no need to provide the credentials in the boto3.client command. See: Configuring the AWS CLI - AWS Command Line Interface - John Rotenstein

2 Answers

1
votes

I also faced the same issue which is mentioned above and i tried the above mentioned suggestions as well but no luck. Then i realized that the AWS account which i used for testing is not authorized. So i added the below in the Trusted Relationship under role summary page in AWS console to authenticate the AWS account.

{
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:root"
      },
      "Action": "sts:AssumeRole"
}

Its started working. I believe it may helpful to new guys to AWS like me.

-2
votes

Finally I found the solution, I have updated the connection object as follows and it works form me -

sts_connection = boto3.client('sts')
assumed_role_object = 
sts_connection.assume_role(RoleArn=my_role_arn,RoleSessionName=str(rolid))

We need to pass "sts" in boto3 client object and in sts connection object need to pass your role arn and roleId for you want to create Federated login link.