Using SAML and token exchange to federate into AWS through the AWS Command Line Interface
This use case shows you how to use PingFederate to issue a token to Amazon Web Services (AWS) to authenticate an end-user for API access.
You can automate getting the AWS Access Key ID and AWS Secret Access Key (which are your account credentials) by using PingFederate to authenticate against the user store (such as ActiveDirectory), get a SAML assertion to federate into AWS, and then exchange the SAML assertion for an access token to make CLI commands to AWS.
Before you begin
Make sure of the following:
-
PingFederate 9.2 is installed and running.
-
You have a functioning AWS SP SAML connection in PingFederate. To accomplish this, install the AWS Connector and the AWS CLI tool. For documentation on the AWS Command Line Interface (CLI), see the Amazon CLI User Guide.
The CLI tool is installed on your hard drive (usually in a hidden folder) and includes two files:
config
andcredentials
. The credentials file is where the ID and Key are stored and look similar to this:aws_access_key_id = ARIAIY4DSCACQLFZSULQ aws_secret_access_key = /zf8dHb2FDJQ0IPxQZeoOLftZ5gif0ve6f8gibtu
Creating a new SP connection in PingFederate
About this task
There are three main contract attributes you need to define in the SP configuration:
The AWS metadata URL (https://signin.aws.amazon.com/static/saml-metadata.xml) includes these attributes and will simplify making the SP connection in PingFederate.
Steps
-
Log in to the PingFederate Administration console.
-
In the SP Connections section of the Identity Provider tab, click Create New.
-
Select Browser SSO Profiles. Click Next.
-
On the Connection Options tab, select the Browser SSO checkbox and click Next.
-
On the Import Metadata tab, select
URL
, Manage Partner Metadata URLs, then Add New URL. -
Add the AWS metadata URL (https://signin.aws.amazon.com/static/saml-metadata.xml), then click Next. Click Save.
-
Select the AWS metadata URL from the Metadata URL list on the Import Metadata tab and then click Load Metadata. Click Next.
-
On the General Info tab, name your connection in the Connection Name field. Click Next.
-
On the Browser SSO tab, click Configure Browser SSO. Select the IDP-Initiated SSO and SP-Initiated SSO checkboxes and click Next until you reach the Assertion Creation tab. Click Configure Assertion Creation.
-
On the Attribute Contract tab, select
urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
from the Subject Name Format list forSAML_SUBJECT
. Click Next.There are several extra attributes included in the AWS metadata URL (such as
urn:oid:1.3.6.1.4.1.5923.1.1.1.1
). These attributes are not required and can be deleted on the Attribute Contract tab. -
On the Authentication Source Mapping tab, click Map New Adapter Instance.
-
Select your adapter instance and click Next until you reach the Attribute Contract Fulfillment tab.
-
On the Attribute Contract Fulfillment tab, select
Text
from the SAML_SUBJECT Source list and in the SAML_SUBJECT Value field, enternull
. -
Select
Text
from the https://aws.amazon.com/SAML/Attributes/Role Source field and in the https://aws.amazon.com/SAML/Attributes/RoleValue
field, enter the value using the following example:arn:aws:iam::<your AWS instance number>:role/<your Role you created in AWS>,arn:aws:iam::<your AWS instance number>:saml-provider/<your SAML Provider you created in AWS>
-
Select
Adapter
from the https://aws.amazon.com/SAML/Attributes/RoleSessionName Source list and selectusername
from the Value list. Click Next and Done until you complete the IdP Adapter Mapping. -
Click Next. Click Done to complete the Assertion Creation configuration.
-
On the Protocol Settings tab, click Configure Protocol Settings.
-
On the Allowable SAML Bindings tab, clear the
Artifact
andSoap
checkboxes and then click Next and Done until you complete the Protocol Settings configuration. -
Click Next then Done to complete the Browser SSO configuration.
-
On the Credentials tab, click Configure Credentials and then select a signing certificate from the Signing Certificate list. Click Done.
-
Click Save on the Activation and Summary tab to complete the SP connection configuration.
Downloading AWS .jar files
Steps
-
Now that you have a functioning SAML connection between your PingFederate and AWS instances, download and install the following:
-
aws-java-sdk-1.11.604.jar
fromaws-java-sdk-1.11.604
. This is available from AWS Downloads. -
All
.jar
files fromlib
ofPingFederate_WS-Trust_STS_Client_SDK-1.1.1
. This is available from PingIdentity.
-
Modifying PingFederate system properties
About this task
Set the pf.idp.wstrust.samlp.resp
system property to true
.
Steps
-
Do one of the following depending on how you are running PingFederate:
-
If your PingFederate is running as a Windows service, this is done in
<PF install location>\pingfederate\sbin\wrapper\PingFederateService.conf
-
Find the
# Java Additional Parameters
section. -
Attribute the next number in the list to a
wrapper.java.additional
parameter. For example:wrapper.java.additional.15=-Dpf.idp.wstrust.samlp.resp=true
-
-
If you are not running PingFederate as a Windows service, you will need to append the appropriate run file in the bin folder (
run.bat
orrun.sh
). For example, inrun.sh
addJAVA_OPTS="$JAVA_OPTS -Dcom.ncipher.provider.announcemode=on -Dpf.idp.wstrust.samlp.resp=true"
-
-
Restart PingFederate. Learn more in Start and stop PingFederate (page 22).
Creating a token processor
Steps
-
In the PingFederate Administrative console, click the System tab and then click Protocol Settings. Click the Roles & Protocols tab.
-
Select the WS-Trust checkbox for IDP roles. Click Save.
-
On the Identity Provider tab, click Token Processors and then click Create New Instance.
-
Enter the appropriate values in the Instance Name and Instance ID fields. From the Type menu, select Username Token Processor. Click Next.
-
From the
Password Credential Validator Instance
menu, select your password credential validator instance. Click Next. -
Click Next and Done until you complete the Token Processor Instance configuration.
Only the
username
attribute is required in the Contract.
Changing the AWS SAML connection to use WS-Trust STS
About this task
Change the AWS SP SAML connection to use the STS processor and map the attributes.
Steps
-
On the Identity Provider tab, from the SP connections list, select your AWS connection.
-
Click Connection Type and select the WS-Trust STS checkbox. Click Next.
-
On the WS-Trust STS tab, click Configure WS-Trust STS and enter
https://signin.aws.amazon.com/saml
in the Partner Service Identifier field. Click Add and then click Next. -
On the Token Creation screen, click Configure Token Creation.
-
Enter
https://aws.amazon.com/SAML/Attributes/Role
in the Extend the Contract field. Click Add. -
Enter
https://aws.amazon.com/SAML/Attributes/RoleSessionName
in the Extend the Contract field and click Add. Click Next. -
On the IdP Token Processor Mapping tab, click Map New Token Processor Instance and specify the token processor. Click Next.
-
Map the Attribute Contract Fulfillment section. See steps 13 - 15 in Creating a new SP connection in PingFederate.
-
Click Next and Save on the Summary tab.
Writing a script to get the security token from AWS
About this task
Write a script to automate the authentication and get the security token from AWS.
Steps
-
The following template is an example script written in
.java
, exported as a runnable.jar
file, and executed in a terminal window.You can write your automation script in any language.
package com.pingidentity.sts; import com.amazonaws.auth.AnonymousAWSCredentials; import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient; import com.amazonaws.services.securitytoken.model.AssumeRoleWithSAMLRequest; import com.amazonaws.services.securitytoken.model.AssumeRoleWithSAMLResult; import com.pingidentity.sts.clientapi.STSClient; import com.pingidentity.sts.clientapi.STSClientConfiguration; import com.pingidentity.sts.clientapi.model.RequestSecurityTokenData; import com.pingidentity.sts.clientapi.model.STSResponse; import com.pingidentity.sts.clientapi.tokens.wsse.UsernameToken; import java.util.Scanner; public class AssumeRoleWithSAMLSample { private static final String PING_STS = " "; https://<pingfedserver>:9031/idp/sts.wst private static final String PRINCIPAL_ARN = "arn:aws:iam::736827903656:saml-provider/PingFed"; private static final String ROLE_ARN = "arn:aws:iam::736827903656:role/Administrators"; public static void main(String[] args) throws Exception { AssumeRoleWithSAMLSample sample = new AssumeRoleWithSAMLSample(); sample.getTemporaryCredential(sample.getSAMLAssertion()); } protected String getTemporaryCredential (String assertion) { AWSSecurityTokenServiceClient client = new AWSSecurityTokenServiceClient(new AnonymousAWSCredentials()); AssumeRoleWithSAMLRequest assumeRoleRequest = new AssumeRoleWithSAMLRequest(); assumeRoleRequest.setPrincipalArn(PRINCIPAL_ARN); assumeRoleRequest.setRoleArn(ROLE_ARN); assumeRoleRequest.setSAMLAssertion(assertion); AssumeRoleWithSAMLResult result = client.assumeRoleWithSAML(assumeRoleRequest); System.out.println(result.toString()); return result.toString(); } protected String getSAMLAssertion () throws Exception { Scanner user_input = new Scanner( System.in ); String username; String password; System.out.print("Enter your AD UserID: "); username = user_input.next(); System.out.print("Enter your AD Password: "); password = user_input.next(); System.out.println("Getting assertion from PingFederate . . ."); STSClientConfiguration stsClientConfiguration = new STSClientConfiguration(); stsClientConfiguration.setStsEndpoint(PING_STS); stsClientConfiguration.setIgnoreSSLTrustErrors(true); STSClient client = new STSClient(stsClientConfiguration); RequestSecurityTokenData requestData = new RequestSecurityTokenData(); requestData.setRequestType(" "); http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue requestData.setTokenType("urn:oasis:names:tc:SAML:2.0:profiles:SSO:browser"); requestData.setAppliesTo(" "); https://signin.aws.amazon.com/saml org.w3c.dom.Element token = null; UsernameToken usernameToken = new UsernameToken(); usernameToken.setUsername(username); usernameToken.setPassword(password); token = usernameToken.getRoot(); STSResponse respData; respData = client.makeRequest(requestData, token, null, null); String result = respData.getRstr().getToken().getFirstChild().getTextContent(); System.out.println("Returninig " + result); return result; } }