Issue: My use case is to authenticate user programatically in Lambda and fetch his credentials using AssumeRoleWithSAML API. Post this I want to use this credential to assume another role in lambda and generate temporary credentials that live longer than 1 hour and don't fall in to role chaining issue. The solution described in stackoverflow here works but I don't want to create an IAM user, instead I want to use federated user credentials to achieve this. Below is my code but I am getting error. Any help is appreciated.
import requests
import boto3
import base64
def authenticate_with_okta(username, password, okta_org_url, okta_app_url):
okta_authn_url = f"{okta_org_url}/api/v1/authn"
# Send a POST request to the Okta Authn endpoint to authenticate the user
response = requests.post(okta_authn_url, json={
"username": username,
"password": password
})
print(response)
if response.status_code == 200:
# Extract the SAML assertion from the response JSON
auth_response = response.json()
saml_assertion = auth_response.get('sessionToken')
if saml_assertion:
return saml_assertion
else:
print(f"Authentication failed. Status code: {response.status_code}")
return None
def decode_saml_assertion(saml_assertion):
try:
decoded_saml = base64.b64decode(saml_assertion)
return decoded_saml
except Exception as e:
print(f"Error decoding SAML Assertion: {e}")
return None
# Decode and print the SAML Assertion
decoded_saml_assertion = decode_saml_assertion
print(decoded_saml_assertion)
def assume_role_with_saml(saml_assertion, role_arn, principal_arn, region_name='us-east-1'):
print("Received SAML Assertion:")
print(saml_assertion)
client = boto3.client('sts', region_name=region_name)
response = client.assume_role_with_saml(
RoleArn=role_arn,
PrincipalArn=principal_arn,
SAMLAssertion=saml_assertion
)
print("STS Response:")
print(response)
return response['Credentials']
def main():
# Replace with your Okta credentials and configuration
okta_username = "MyOktaUser@lab.com"
okta_password = "MyComplexPassword"
okta_org_url = "https://mydomain.okta.com" # Replace with your Okta domain URL
okta_app_url = "https://mydomain/home/amazon_appstream/0oa8alauh3v3ise4C5d7/aln1al3ek55Es08M81d8" # Replace with your Okta app URL
# Replace with your AWS role ARN and principal ARN
aws_role_arn = "arn:aws:iam::1234567890:role/Test_Role"
aws_principal_arn = "arn:aws:iam::1234567890:saml-provider/Okta"
# Step 1: Authenticate with Okta and get SAML Assertion
saml_assertion = authenticate_with_okta(okta_username, okta_password, okta_org_url, okta_app_url)
if not saml_assertion:
print("Failed to obtain SAML Assertion.")
return
# Step 2: Use SAML Assertion to Assume AWS Role and get temporary credentials
try:
credentials = assume_role_with_saml(saml_assertion, aws_role_arn, aws_principal_arn)
print("Temporary credentials fetched successfully!")
print("Access Key ID:", credentials['AccessKeyId'])
print("Secret Access Key:", credentials['SecretAccessKey'])
print("Session Token:", credentials['SessionToken'])
except Exception as e:
print("Error assuming AWS role:", e)
if __name__ == "__main__":
main()
Error
Received SAML Assertion:
20111Fw2lcP1_zs-PI6z_9dF5A_-TcIbDwv-5zWaVsg4GP6SiUA_9s0
Error assuming AWS role: An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithSAML operation: Invalid base64 SAMLResponse (Service: AWSOpenIdDiscoveryService; Status Code: 400; Error Code: AuthSamlInvalidSamlResponseException; Request ID: 80a016bb-17ca-4162-bf68-08f63eba32d2; Proxy: null)
@Tutan Ramen in the above link figured to workout something but not sure how.
Code and information is above