Application Delivery Management
Application Modernization & Connectivity
CyberRes
IT Operations Management
Authors:
Eduardo Barragan, Novacoast, Inc.
Neil Cashell, Novell, Inc.
Table of Contents
Document Change Tracking
Introduction
Shibboleth IdP Access Manager specific setup
Define the Metadata Provider
Add new SP Metadata
Define Relying Party
Add Persistent nameIDFormat to attribute-resolver.xml
Create the attribute definitions with dependencies
Access Manager Service Provider setup – Add new SAML 2 Trusted Provider
Create the Trust
Illustration 1: Import the IdP Metadata via text
Illustration 2: Import IdP Trusted Root cert - Add it to the NIDP-truststore
Configure the Trusted Provider
Illustration 3: Matching Expression used
Illustration 4: Configure Trust Security - no name id encryption
Illustration 5: Configure the Authentication Request
Illustration 6: Novell Access Manager Logging Configuration
Illustration 7: Obtaining Attributes for matching
Illustration 8: Configure User ID method for Attribute Matching
Illustration 9: Configure the user Matching Method
Accessing the Service Provider
Illustration 10: Authentication Card ID
Illustration 11: Shibboleth Default IdP Login Page
Problems Encountered
Conclusion
Contributors: Eduardo Barragan, Novacoast, Inc and Neil Cashell, Novell, Inc
Created by: Eduardo Barragan - Revision 1: 02/09/09
This document describes a SAML2 SP-initiated SSO exchange between a Novell Access Manager 3.1 SAML2 Service Provider (SP) and a Shibboleth SAML2 Identity Provider (IdP). Within this exchange, the user attempts to access a resource on the SP. Since the user has no active session on this SP, the user is asked to login and selects to do so via the IdP server which is references in the SAML trust relationship. As a result, the user is sent to the IdP server to login and the IdP, once the users credentials are validated, provides a SAML web SSO assertion for the user's federated identity back to the SP.
For this example, the POST Binding is used to deliver the SAML <AuthnRequest> message to the IdP server, as well as returning the SAML response message containing the assertion to the SP. In terms of the high level flow, the following sequence of events take place:
<form method="post" action="https://idp.shiboli.org/SAML2/SSO/POST" ...>
<input type="hidden" name="SAMLRequest" value="request" />
<input type="hidden" name="RelayState" value="token" />...
<input type="submit" value="Submit" />
</form>
The value of the SAMLRequest parameter is the base64 encoding of the following:
<samlp:AuthnRequest> element:
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Consent="urn:oasis:names:tc:SAML:2.0:consent:unavailable" ForceAuthn="false" ID="idEZzUpQd6fWcP5dgXUBMdex5m6LU" IsPassive="false" IssueInstant="2009-02-06T21:42:59Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0">
<saml:Issuer>https://sp.novacoast.com:8443/nidp/saml2/metadata</saml:Issuer>
<samlp:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"/>
<samlp:RequestedAuthnContextComparison="exact">
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContext ClassRef>
</samlp:RequestedAuthnContext>
</samlp:AuthnRequest>
POST /idp/profile/SAML2/POST/SSO
Host: idp.shiboli.org
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.17) Gecko/20080921 SUSE/2.0.0.17-0.2.1 Firefox/2.0.0.17
Accept-Encoding: gzip,deflate
Keep-Alive: 300
Connection: keep-alive
Referer: https://sp.novacoast.com:8443/nidp/saml2/spsend?id=Shibboleth&sid=1
Cookie: _idp_authn_lc_key=_cc0dd1db286247356c2ec5baec1ef960; JSESSIONID=F5DF233B7FE0FF15FF8624A233C8E944; _idp_session=MTkyLjE2OC4xLjIwMQ==|YjQ2MDFkZWEwM2YwZTc1NjEzNGQ2MGY0OGE2Zjk4YWRlMmU4ZDNiODUyZWE0YWI3ZTdkZTU5ZDM3OTQzMzQ5NA==|Ai1jxQu4sY5cf0mMKkGJTaKCIV4=
Content-Type: application/x-www-form-urlencoded
Content-Length: 1126
SAMLRequest=Base64Request&RelayState=MQ==
<samlp:Response>
<saml:Assertion>
:
<saml:Subject xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">_63931742a0e7ae069ccf7acf7e841001</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData Address="192.168.1.201" InResponseTo="idd20eOfXddQjWU.lGABiVwwx24R8" NotOnOrAfter="2009-02-06T21:48:47.416Z" Recipient="https://sp.novacoast.com:8443/nidp/saml2/spassertion_consumer"/></saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2009-02-06T21:43:47.416Z" NotOnOrAfter="2009-02-06T21:48:47.416Z" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:AudienceRestriction><saml:Audience>https://sp.novacoast.com:8443/nidp/saml2/metadata</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2009-02-06T21:43:47.376Z" SessionIndex="293482f7f2b3b2df3dc63b9daea6e610cabd07e2fe102d5d6ff6422c6c2b4bf6" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:SubjectLocality Address="192.168.1.201"/>
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
<saml:AuthnContextDeclRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextDeclRef>
</saml:AuthnContext>
</saml:AuthnStatement>
:
<saml:AttributeStatement xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">testuser</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="sn" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">User</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="cn" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">testuser</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="givenName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">**</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>
You must follow and understand the basic Shibboleth IdP 2.1 install process. This is not a production ready configuration, there are may security considerations to be dealt with in order for the IdP to be secured. The installation can be done on SLES 10Sp1 and above with Apache Tomcat 5.5 and Sun Jre 1.6.
https://spaces.internet2.edu/display/SHIB2/IdPInstall
Before entering any SAML trust relationship, a SAML device needs to have it's metadata defined, according to the SAML2 metadata specifications. To populate the Shibboleth IDP server metadata, follow the details included in the following URL: https://spaces.internet2.edu/display/SHIB2/IdPMetadataProvider
The SP metadata can be obtained via a standard web browser or using tools like curl and wget. The URL of the metadata in this case is stored under the /saml2/metadata path, since it's a SAML 2 federation. The full URL should resemble this: https://your domain:8443/nidp/saml2/metadata
The entry needed here is using a stored file (metadata-SP.xml)containing the SP metadata.
<MetadataProvider id="your domainMD" xsi:type="ResourceBackedMetadataProvider" xmlns="urn:mace:shibboleth:2.0:metadata">
<MetadataResource xsi:type="resource:FilesystemResource" file="/opt/shibboleth-idp/metadata-SP.xml" />
</MetadataProvider>
This configuration basically defines the details of each protocol and service being supported, in this example we are using SAML2 and selecting the parameters of the artifact resolution and attribute query profile. Other protocols and profiles can be defined here.
<RelyingParty id="your domain" provider="https://your domain:8443/nidp/saml2/metadata"
defaultSigningCredentialRef="IdPCredential">
<ProfileConfiguration xsi:type="saml:SAML2SSOProfile"
assertionLifetime="300000"
assertionProxyCount="0"
encryptAssertions="never"
signAssertions="conditional"
encryptNameIds="never"
signResponses="never" />
<ProfileConfiguration xsi:type="saml:SAML2ArtifactResolutionProfile"
signResponses="conditional"
signAssertions="never"
encryptAssertions="conditional"
encryptNameIds="conditional"/>
<ProfileConfiguration xsi:type="saml:SAML2AttributeQueryProfile"
assertionLifetime="300000"
assertionProxyCount="0"
signResponses="conditional"
signAssertions="never"
encryptAssertions="conditional"
encryptNameIds="conditional" />
</RelyingParty>
To handle the incoming SAML Authentication requests from the Novell Access Manager SP, the NameIDFormat on the Shibboleth servers attribute-resolver.xml file must have an entry matching the NameIDFormat sent in the request (See Problems Encountered section for more detail)
<!-- Principal Connectors -->
<resolver:PrincipalConnector xsi:type="Transient" xmlns="urn:mace:shibboleth:2.0:resolver:pc" id="saml2Persistent"
nameIDFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" />
<!-- Name Identifier related attributes -->
<resolver:AttributeEncoder xsi:type="SAML2StringNameID" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
nameFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" />
See Problems Encountered section for more detail
https://spaces.internet2.edu/display/SHIB2/IdPAddAttribute
In order to create an attribute statement in the assertion, one must define (attribute-resolver.xml and release (attribute-filter.xml) attributes. The dependencies are based in this case on the data connector defined as “myLDAP” This is an example of the content needed for some basic attributes:
<resolver:AttributeDefinition id="cn" xsi:type="Simple" xmlns="urn:mace:shibboleth:2.0:resolver:ad"
sourceAttributeID="cn">
<resolver:Dependency ref="myLDAP" />
<resolver:AttributeEncoder xsi:type="SAML2String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
name="cn" />
</resolver:AttributeDefinition>
<resolver:AttributeDefinition id="givenName" xsi:type="Simple" xmlns="urn:mace:shibboleth:2.0:resolver:ad"
sourceAttributeID="givenName">
<resolver:Dependency ref="myLDAP" />
<resolver:AttributeEncoder xsi:type="SAML2String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
name="givenName" />
</resolver:AttributeDefinition>
<!-- Release these attributes to anyone -->
<AttributeFilterPolicy id="releaseTransientIdToAnyone">
<PolicyRequirementRule xsi:type="basic:ANY" />
<AttributeRule attributeID="transientId">
<PermitValueRule xsi:type="basic:ANY" />
</AttributeRule>
</AttributeFilterPolicy>
<AttributeFilterPolicy id="releasecnToAnyone">
<PolicyRequirementRule xsi:type="basic:ANY" />
<AttributeRule attributeID="cn">
<PermitValueRule xsi:type="basic:ANY" />
</AttributeRule>
<AttributeFilterPolicy id="releasegivenNameToAnyone">
<PolicyRequirementRule xsi:type="basic:ANY" />
<AttributeRule attributeID="givenName">
<PermitValueRule xsi:type="basic:ANY" />
</AttributeRule>
</AttributeFilterPolicy>
The Shibboleth metadata file is located in the $IDP_HOME/metadata/idp-metadata.xml and is created by the install script.
Importing the metadata file on the Access Manager SP notifies the SP of identifiers, binding support and URL endpoints, certificates and keys, and so forth. When the SP needs to send a request to the IDP server to login as an example, it retrieves the login URL from the metadata <SingleSignOnService> tag defined in the metadata.
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://idphost.amgconsulting.com/idp/profile/SAML2/POST/SSO"/>
The IdP Trusted Root certificate can be attained by going to the IdP webapp base URL once you deploy the application.
Configure the Trusted Provider
Before you configure the Identity Provider attributes or User Identification, create an Attribute Set and a User Matching Expression – doing this will make the proper attributes available for the configuration.
By default the Shibboleth IdP does not sign or encrypt name identifiers or assertions, it will follow the SP configuration however when set to “conditional” in the attribute-reslver.xml. Access Manager does require signed assertions when using the HTTP-POST protocol profile.
The Authentication Request configuration defines how the authentication request from Access Manager behaves, in this case we are using the HTTP-POST profile for protocol binding, the other options on this page (not shown) should be unchecked.
With the IDP Cluster logging set to the debug settings in the following screenshot, the SAML2 Authentication request will be displayed in the catalina.out file on the Access Manager SP. The binding is SAML2 POST.
************************* SAML2 POST message ********************************
Type: sent
Sent to: https://idphost.amgconsulting.com/idp/profile/SAML2/POST/SSO RelayState: MA==
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Consent="urn:oasis:names:tc:SAML:2.0:consent:unavailable" ForceAuthn="false" ID="idEZzUpQd6fWcP5dgXUBMdex5m6LU" IsPassive="false" IssueInstant="2009-02-06T21:42:59Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0">
<saml:Issuer>https://sp.novacoast.com:8443/nidp/saml2/metadata</saml:Issuer>
<samlp:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"/>
<samlp:RequestedAuthnContextComparison="exact">
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</samlp:RequestedAuthnContext>
</samlp:AuthnRequest>
************************* End SAML2 message ****************************
From here, we can confirm that the SP is using the POST binding in the AuthnRequest, as defined in the configuration details above, and the NameID format to be used is persistent.
Select the attributes you will use in your matching expression – this is how you will uniquely identify the user, in this example, it's very simple.
By defining the attributes to be obtained during authentication, the Access Manager SP will expect a SAML attribute assertion to be sent by the IDP server. The following entry from the catalina.out file shows a snippet of the Shibboleth assertion's AttributeStatement containing the attributes requested.
<samlp:Response>
<saml:Assertion>
<saml:AttributeStatement xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">testuser</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="sn" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">User</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="cn" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">testuser</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="givenName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">**</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>
Select the matching expression you created under Shared Settings previously as in Illustration 9.
When the SAML assertion comes in to the Access Manager SP, issued by the IdP server, we will retrieve the attribute names and values from the AttributeStatement. An LDAP lookup will be performed on the local user store (eDir in above example) to identify is a corresponding user exists. Assuming that user exists, the user will be authenticated at the SP too. Below is an example of the LDAP search trace:
<amLogEntry> 2009-02-06T21:43:08Z NIDS Trace: Method: WSFXPath.<init>() Thread: http-192.168.1.35-8443-Processor10 Creating a WSFXPath in model: LDAP Attribute Profile for XPath: /UserAttribute[@ldap:targetAttribute="givenName"] </amLogEntry>
<amLogEntry> 2009-02-06T21:43:08Z NIDS Trace: Method: LdapSearcher.search() Thread: http-192.168.1.35-8443-Processor10 Searching on User Store: cn=US45w0ei,cn=Assz8q5,cn=SCCubkdbq,cn=cluster,cn=nids,ou=accessManagerContainer,o=novell. Ldap Search Filter: (&(&(givenName=Eduardo))(objectClass=User)) </amLogEntry>
<amLogEntry> 2009-02-06T21:43:08Z NIDS Trace: Method: JNDIUserStore.doAdminSearch()
Thread: http-192.168.1.35-8443-Processor10 (1 of 3):
Base context: ou=ssousers,o=sso, Filter: (&(&(givenName=Eduardo))(objectClass=User)), Scope: 1, Request Controls: null, UserId: cn=admin,o=novell (2 of 3):
Try connection: ldaps://192.168.1.36 (3 of 3):
Found 1 results!
Accessing the Service Provider
In this case, as described in the introduction to this document, we are using SP initiated SSO. We will use an Inter Site Transfer Service URL built for AM 3.1 specifically.
https://sp.novacoast.com:8443/nidp/saml2/spsend?id=Shibboleth&sid=1&TARGET=https://destinationURL
The components of this URL contain the SP URL, then a reference to the Shibboleth IdP using the Id assigned in the Authentication Card setup (see below) and finally the destination service URL.
When the user uses this URL, they will be sent to the IdP's default login page ( Illustration 11) for the previously configured authentication method, in this case, username and password. As with Access Manager 3.1, the Shibboleth login page can also be branded and configured for different SP's.
When processing the SAML2 response at the IdP server, it would return a message in the logs about the NameID format not being supported. Looking at the SAML response to the AuthnRequest, we would see the following:
:
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Responder"><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy"/></samlp:StatusCode><samlp:StatusMessage>Format not supported: urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</samlp:StatusMessage>
</samlp:Status>
</samlp:Response>
Turns out that the NameIDFormat advertised in the SAML AuthnRequest ( urn:oasis:names:tc:SAML:2.0:nameid-format:persistent) was not available on the Shibboleth side. Adding this format to the Shibboleth configuration avoided the issue. The default NameIDFormat entries were
urn:mace:shibboleth:1.0:nameIdentifier
urn:oasis:names:tc:SAML:2.0:nameid-format:transient
When using the POST profile to send an assertion response to the SP, the Liberty specifications require that signing be enabled. The Shibboleth server was not signing the assertion response and the SP was throwing the above error.
The SP was configured to match users based on attribute values returned in the AuthenticationStatement. The SP expected an AttributeStatement to include the attribute name and value. By default, Shibboleth encodes the attribute information in an XML format. The assertion included the AttributeStatement in the following format:
<saml:AttributeStatement xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:Attribute FriendlyName="uid" Name="urn:oid:0.9.2342.19200300.100.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">**</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute FriendlyName="cn" Name="urn:oid:2.5.4.3" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">**</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>
Had to change the attribute-resolver.xml file on the Shibboleth IDP server to send back the attributes in the name/value format expected by the SAML SP.
When configuring Tomcat, the directions add port 8443, but for some reason the IdP metadata listed the provider on the default HTTPS port.
Added iptables script to redirect 443 to 8443 to resolve discrepancies, the metadata could be edited as well, but keeping track of that can difficult if you redeploy the web application.
#iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to 192.168.1.205:8443
Identity Federation is an excellent tool for seamlessly integrating loosely coupled name spaces. It's built on well-known standards like SAML and is available from both commercial and open source offerings. This is a good example of how this standard is well understood and implemented in Access Manager. Interoperability can be achieved easily “out-of-the-box” between Access Manager 3.1 and Shibboleth 2.1 IdP using SAML (1.1 or 2) proving that this technology is ready for some of the challenging complex business, government and educational identity needs today.