AWS Boto3 - User is not authorized to perform sts::AssumeRole on resource?

Rahul Gaikwad picture Rahul Gaikwad · Jul 27, 2018 · Viewed 7.3k times · Source

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?

Answer

Krishnappan Palaniappan picture Krishnappan Palaniappan · Oct 11, 2019

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.