Skip to content

Instantly share code, notes, and snippets.

@mhvelplund
Created January 21, 2020 18:02
Show Gist options
  • Save mhvelplund/fb61a126bc48d4603be6edc66a3cf167 to your computer and use it in GitHub Desktop.
Save mhvelplund/fb61a126bc48d4603be6edc66a3cf167 to your computer and use it in GitHub Desktop.
Create temporary AWS credentials using ADFS2 SAML.
#!/bin/bash
# If you're unfamiliar with this syntax,
# $1, $2 ... are the position arguments
# to this script. The ${1:-DEFAULT} means
# that if there is no argument given,
# DEFAULT is used.
# So you could either fill in the defaults
# and only type your password, or you could
# call
# ./script myusername arn:aws:iam::something arn:aws:iam::something us-west-2 different-ad-domain different-adfs-server-location
ADFSUSER=${1:-YOURDEFAULTUSERNAME}
ROLEARN=${2:-arn:aws:iam::YOURDEFAULTACCOUNT:role/YOURDEFAULTROLE}
PRINCIPLEARN=${3:-arn:aws:iam::YOURDEFAULTACCOUNT:saml-provider/YOURDEFAULTPROVIDER}
AWS_DEFAULT_REGION=${4:-us-east-1}
ADFSDOMAIN=${5:-YOURDEFAULTDOMAIN}
ADFSURL=${6:-YOURDEFAULTHOSTNAMEFORADFS}
read -p "Password: " -s PASSWORD
# create a newline
echo
# First, URI encode the password since it may include special characters like " or # or !
PASSWORD=$(perl -e "use URI::Escape; print uri_escape(\"${PASSWORD}\");")
# Scrapped from the ADFS webpage; note that %5C is '\', so you get DOMAIN\username
POSTDATA="UserName=${ADFSDOMAIN}%5C${ADFSUSER}&Password=${PASSWORD}&AuthMethod=FormsAuthentication"
# Clear out cookies file
:> cookies.txt
# First we do a POST, ignoring the output but writing to the cookies file
curl -s -c cookies.txt -X POST --data $POSTDATA "https://${ADFSURL}/adfs/ls/idpinitiatedsignon/?loginToRp=urn:amazon.webservices" >/dev/null
# Then we read & and write cookies here, since we get redirected twice
# Besides the SessionCookies, you absolutely need the MSISLoopDetectionCookie
# The second redirect actually produces very basic HTML page with an
# instant Javascript redirect to POST to signin.aws.amazon.com/saml
# with the SAMLReponse header. So we grab the file, cut out the
# irrelevant parts, and then save just the SAMLReponse string,
# thankfully already base64 encoded.
# The perl regex may flake out, but works at the moment.
curl -s -L -c cookies.txt -b cookies.txt -X GET "https://${ADFSURL}/adfs/ls/idpinitiatedsignon/?loginToRp=urn:amazon:webservices" | perl -ple 's/^.*?value="//g ; s/==.*$//g' > saml_resp.b64
#curl -s -L -c cookies.txt -b cookies.txt -X GET "https://${ADFSURL}/adfs/ls/idpinitiatedsignon/?loginToRp=urn:amazon:webservices" | perl -ple 's/^.*?value="//g ; s/".*$//g' > saml_resp.b64
# The --saml-assertion requires a base64 encoded string,
# and it can't be read from a file
# The output is some lovely JSON
aws sts assume-role-with-saml --role-arn $ROLEARN --principal-arn $PRINCIPLEARN --saml-assertion $(cat saml_resp.b64) > assumed-role.json
# Take the JSON and extract the three things we need:
# Secret Access Key, Access Key, and the Session Key
# For convenience I then take those three, convert
# them to the environment variables that AWS CLI
# tool expects, along with a leading 'export'
# so it's ready to copy and paste, or potentially
# even just be source'd.
# The JSON file is kept around and is useful for humans
# since it has the expiration time and such
cat assumed-role.json | grep -E 'Key|Session' | sed -e 's/: /=/g' -e 's/^ /export/g' -e 's/,//g' -e 's/SecretAccessKey/AWS_SECRET_ACCESS_KEY/' -e 's/AccessKeyId/AWS_ACCESS_KEY_ID/' -e 's/SessionToken/AWS_SESSION_TOKEN/'
# For convenience, although this could
# also be set in the ~/.ec2/config
# or on the command line
echo "export AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment