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
Our oauth proxy
Our business proxy
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.
https://api.enterprise.apigee.com/v1/organizations/dbcjd/environments/test/keystores
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
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
10. Verify using Web UI look at Admin/TLS Certificates
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>
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>
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
1. Use Developer Apps, Consumer Key as a client_id query parameter
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.
Hi @yuriyl
Could you please provide me the Git link for above SAML code.
Can this be done in the free trial account?