SAML Assertion Policies Study

Introduction

Edge has two simple but powerful policies, that let us use Edge as an IdP or SP points of a SAML2-enabled solution.

Their documentation, http://docs.apigee.com/api-services/reference/saml-assertion-policy, is comprehensive but terse. To understand them better, let's experiment with those policies, using simple but complete test harness.

The current design and requirements of our little project assume an ability to swap the OAuth2 access_token for the SAML Assertion, when the Edge will be functioning as an IdP and that could be accepted by a Target Server.

The key design decisions of our solution are:

Our client application

  • Upon providing client credentials;
  • exchanges them for OAuth2 access_token.
  • uses the access_token to interact with a SAML-enabled backend.

Our oauth proxy

  • After validating user credentials,
  • Uses Generate SAML Assertion policy to create the assertion;
  • And stores it as an Attribute when generating an access_token.

Our business proxy

  • After Verifying provided access_token, the SAML assertion is automatically fetched and added to a SOAP message;
  • Then it is expected to be verified by an BackEnd SAML SP.

The SAML test harness will have two proxies samlidp and samlsp. To validate digital signature on SAML assertions we need X.509 certificates. We will use openssl to generate self-signed certificate for our setup.

KeyStore with X.509 Certificates

Create and upload keystore

To list keystores:

https://api.enterprise.apigee.com/v1/organizations/dbcjd/environments/test/keystores

Create self-signed SSL Certificate

WARNING: Your certificate is not working? Meet the Logjam, https://www.openssl.org/blog/blog/2015/05/20/logjam-freak-upcoming-changes/.

Check the version of your openssl package. If it is older than 1.0.2, the generated certificate will not be accepted by a later Node.js interpreter. As Node.js uses openssl libraries, chances are you have fresh node but stale openssl utility.

1. Generate RSA key. In the Terminal enter

openssl genrsa -out mockserver.key

The mockserver.key file will be generated.

2. Create a certificate signing request (CSR) for an SSL certificate. Answer the questions

openssl req -new -key mockserver.key -days 3650 -out mockserver.csr

Country Name (2 letter code) [AU]:UK

State or Province Name (full name) [Some-State]:Surrey

Locality Name (eg, city) []:Guildford

Organization Name (eg, company) [Internet Widgits Pty Ltd]:Mock Server Ltd

Organizational Unit Name (eg, section) []:mockdept

Common Name (e.g. server FQDN or YOUR name) []:mockserver.com

Email Address []:admin@mockserver.com

A challenge password []: <Enter>

An optional company name []: <Enter>

An .csr file will be created.

3. Create the certificate from the certificate request

openssl x509 -req -days 3650 -in mockserver.csr -signkey mockserver.key -out mockserver.crt

Signature ok

subject=/C=UK/ST=Surrey/L=Guildford/O=Mock Server Ltd/OU=mockdept/CN=mockserver.com/emailAddress=admin@mockserver.c

om

Getting Private key

To create a keystore

See also: http://docs.apigee.com/api-services/content/keystores-and-truststores

1. "create" .pem files in the mockserverKeystore folder

cp mockserver.crt mockserverKeystore/mockserverCrt.pem

cp mockserver.key mockserverKeystore/mockserverKey.pem

2. Make a folder for a jar file mockserverKeystore

3. In the folder, create: sub-folder META-INF

4. In the META-INF create a descriptor.properties file and add following lines:

certFile=mockserverCrt.pem

keyFile=mockserverKey.pem

5. Inside the mockserverKeystore folder run commands

jar -cf mockserverKeystore.jar mockserverCrt.pem mockserverKey.pem

jar -uf mockserverKeystore.jar META-INF/descriptor.properties

NOTE: Example ~/.netrc file for curl -n option:

machine api.enterprise.apigee.com login name@gmail.com password psw2

machine 192.168.56.102 login admin@apigee.com password Apigee2016

6. List the keystores

curl https://api.enterprise.apigee.com/v1/organizations/dbcjd/environments/test/keystores -nv

7. Create a KeyStore object

curl -H "Content-Type: text/xml" \

https://api.enterprise.apigee.com/v1/organizations/dbcjd/environments/test/keystores \

-d '<KeyStore name="mockserverKeystore"/>' -nv

8. Add the .jar into the keystore

curl -X POST -H "Content-Type: multipart/form-data" \

-F file="@mockserverKeystore.jar" \

"https://api.enterprise.apigee.com/v1/organizations/dbcjd/environments/test/keystores/mockserverKeystore/keys?alias=mockserver" -nv

9. Verify using curl

curl https://api.enterprise.apigee.com/v1/organizations/dbcjd/environments/test/keystores/mockserverKeyst... -nv

10. Verify using Web UI look at Admin/TLS Certificates

SAML Proxies

Saml IdP Proxy

1. Proxy no target;

2. Generate Product checkbox

3. Add Generate SAML Assertion policy

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<GenerateSAMLAssertion ignoreContentType="true" name="Generate-SAML-Assertion">

<DisplayName>Generate SAML Assertion</DisplayName>

<KeyStore>

<Name ref="reference">mockserverKeystore</Name>

<Alias ref="reference">mockserver</Alias>

</KeyStore>

<Subject>subject</Subject>

<Issuer>issuer</Issuer>

<Template ignoreUnresolvedVariables="false"><![CDATA[

<saml:Assertion Version="2.0"

ID="SAML-rcFM3cPB5RIi6DGbJVJeDQ44" IssueInstant="2015-04-18T11:37:23Z"

xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">

<saml:Issuer>www.oracle.com</saml:Issuer>

<saml:Subject>

<saml:NameID

Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">USERNAME</saml:NameID>

<saml:SubjectConfirmation

Method="urn:oasis:names:tc:SAML:2.0:cm:sender-vouches" />

</saml:Subject>

<saml:Conditions NotBefore="2014-09-17T10:47:22Z"

NotOnOrAfter="2017-09-17T10:52:22Z" />

<saml:AuthnStatement AuthnInstant="2014-09-17T10:47:22Z">

<saml:AuthnContext>

<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef>

</saml:AuthnContext>

</saml:AuthnStatement>

</saml:Assertion>

]]></Template>

<OutputVariable>

<FlowVariable name="assertion.content"/>

</OutputVariable>

</GenerateSAMLAssertion>

4. Add OAuthV2.GenerateAccessToken policy

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuthV2GenerateAccessToken">

<DisplayName>OAuthV2.GenerateAccessToken</DisplayName>

<Operation>GenerateAccessTokenImplicitGrant</Operation>

<GenerateResponse enabled="true"/>

<Attributes>

<Attribute name="saml.assertion" ref="assertion.content" display="true"/>

</Attributes>

<Tokens/>

</OAuthV2>

Saml SP Proxy

1. Proxy No Target;

2. Generate Product checkbox

3. Add Verify OAuth v2.0 Access Token policy

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<OAuthV2 async="false" continueOnError="false" enabled="true" name="verify-oauth-v2-access-token">

<DisplayName>Verify OAuth v2.0 Access Token</DisplayName>

<Operation>VerifyAccessToken</Operation>

</OAuthV2>

Developer App Configuration

1 Create saml-app Developer App

Developer: Nikolai Tesla

Callback URL http://localhost:2999

2. Add samlidp Product and samlsp Product to the app.

3. Save

Test Request

1. Use Developer Apps, Consumer Key as a client_id query parameter

http://dbcjd-test.apigee.net/samlidp?response_type=token&redirection_uri=http://localhost:2999&clien...

http://localhost:2999/#scope=&expires_in=1799&access_token=uzB6lBLPcNZGUdeegE4EJEsWbkE3

2. Postman request with Authorization: Bearer header

3. In the trace we can see fetched Attribute of the OAuthv2 Verify Access Token policy.

Comments
Not applicable

Hi @yuriyl

Could you please provide me the Git link for above SAML code.

hsbhattacharjee
New Member

Can this be done in the free trial account?

Version history
Last update:
‎02-06-2017 07:48 AM
Updated by: