Wikis - Page

Configuring IDM 4.5s OSP to talk to a Shibboleth IDP

0 Likes
Steps to get OSP talking to Shibboleth IDP:

In the world of federation there are many possible tools and protocols to use. There is an alphabet soup of acronyms like SAML, WS-Fed, WS-*, Shibboleth, Liberty, SOAP or REST, Oauth, etc. There are a host of products that can do this for you. NetIQ has one called NetIQ Access Manager (NAM) but there are other products out there like CA's Siteminder, Microsoft's ADFS, and even some cloud based solutions. Okta makes a cloud only federation product (which is a bit of a mixed bag in my view. It is ok if you stay within its very limited functionality, just do not step outside those boundaries. The places you would want to extend it, you would have a hard time doing so, regardless of claims about APIs that they have. Within its boundaries it is fine). NetIQ has a cloud solution for stuff like this, that you can own in house, Cloud Access/Social Access/Mobile Access which all use, under the covers, the same federation engine, and they call it OSP. One SSO Provider.

If you read the documentation for IDM 4.5 you will see that OSP is now the underlying SSO engine for the web based components of the IDM product. That is, User Application (/IDMProv), Home and Provisioning Dashboard (/landing and /dash), Reporting (/IDMRPT), Catalog Access (/rra), and Access Review (if you bought it) all use this one SSO solution for internal SSO.

That is an important point, 'internal SSO'. What happens is, once you login to OSP once, you are now able to SSO to the above listed components. OSP supports three methods of logging in.

First is the default, Name and Password that we are all familiar with. You hit a web page (https://server/osp/auth) and you get a JSP page asking for Username and Password. (It might have a Forgotten Password link there as well, if you enable it in configupdate.sh).

Second is Active Directory Kerberos integration. In that case, OSP is set to support Kerberos, and if your workstation is logged into an Active Directory Domain, and you have a valid Kerberos ticket then OSP accepts that ticket to authenticate you to the SSO of internal IDM applications.

Third is the interesting one to me here, and that is SAML (Security Assertion Markup Language), and you can go read on Wikipedia all about it. http://en.wikipedia.org/wiki/Security_Assertion_Markup_Language

SAML is a nice federation standard that is in fact, pretty standard. Which is kind of surprising to me. This is an actual standard that is kind of standard. Usually someone big makes a big change, since they are the big dog, every has no choice but to accommodate and the standard is no longer standard. For the most part SAML has avoided that, which is nice.

Now NAM supports SAML well, as do its competitors. But if you are working at a University in the United States, odds are very good that you are using a Shibboleth system for federation. Shibboleth (the word is sort of a biblical joke, where the word, when said in Hebrew has two pronunciations and that was used to determine the origin of people. Can you say it both ways?) is sort of an add on, on top of SAML. That is Shibboleth adds some additional functionality but uses SAML mostly under the covers to federate with other sites.

In my case, I needed to get a Shibboleth IDP (Identity Provider) talking to an OSP SP (Service Provider). The IDP is the guy who knows where the users are (buried) and has the ability to let you login. The SP provides a service. That is, the User App is the service, but you need to authenticate to it before you can use it, and you do that on the IDP which can get you logged in, tell the SP, yep I trust that guy, let him in. Then the SP can accept it and let you do what is needed.

In the process of getting this to work, I found a bunch of interesting issues along the way, and I will be writing up a sibling article to this, trying to help people get through the problems I found and avoid wasting time, since it is already solved. For this article I want to focus on what is needed, and why. I love the articles that tell you how to get stuff going for federation, but I wish they would spend more time on the "why". Yes, I need to do exactly this step. But why? I hope to be able to help in this case.

In terms of getting OSP doing SAML it seems like you simply need to do the following:

  • Find out the IDP's metadata URL. (Where it shares an XML document describing what it offers). Your Shibboleth admin will know where this is.

  • Use Configupdate, (Tool used to configure User App/Identity Apps in IDM) go to the Authentication tab, click on the Advanced Settings and change the Authentication Method from Name and Password to SAML 2.0. You tell it the URL for the IDP metadata you just got, and decide what attribute it will look in the IDV to match users. (WorkforceID, email, cn, or something unique is important here).


configUpdate-SAML1 - Copy
 
configUpdate-SAML2 - Copy

That is basically all you need on the OSP end. But... There is always a but.

First up, you need to get the right certificates in use. OSP by default sets itself up with a custom self signed cert when you install it. It uses the osp.jks file and a password you set during install.

What I found best was to start with a fresh keystore, generate a private key, request a signing by a CA (CSR, Certificate Signing Request), send that off to your CA, import the signed response. Now we have a key for Tomcat to use for HTTPS services, and we can use the same or a second key for OSP to use. I used the same one for both.

Some example command to do this.

/opt/netiq/idm/apps/jre/bin/keytool -keysize 2048 -genkey -alias tomcat -keyalg RSA -keystore /opt/netiq/idm/apps/tomcat/conf/tomcat.jks -dname "CN=idmServ.acme.edu, OU=Dept, O=Acme University, L=City, ST=XX, C=US" -validity 1095 -storepass novell


That makes a 2048 bit key, aliased 'tomcat', using RSA algorithms, putting it in the tomcat.jks keystore, with a password novell. It will have a Distinguished name that is quite specific, because the signing CA I used wanted a very specific format for the name. A simpler -dname could be "CN=idmServ.acme.edu" if your CA will sign it that way.

Finally, validity of 3 years. (365*3 days).

Next you need to generate a CSR to send to the CA.

/opt/netiq/idm/apps/jre/bin/keytool -certreq -alias tomcat -file /opt/netiq/idm/apps/tomcat/conf/csr.txt -keystore /opt/netiq/idm/apps/tomcat/conf/tomcat.jks -storepass novell


Next you import the response you got back with:

/opt/netiq/idm/apps/jre/bin/keytool -import -alias tomcat -file /opt/netiq/idm/apps/tomcat/conf/ca-response.txt -keystore /opt/netiq/idm/apps/tomcat/conf/tomcat.jks -storepass novell


Then configure Tomcat in /opt/netiq/idm/apps/tomcat/conf/server.xml with a line like:

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" keyAlias="tomcat" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2" keystoreFile="/opt/netiq/idm/apps/tomcat/conf/tomcat.jks" keystorePass="password" />


(Note this allows TLS not SSL as well. Darn you HEARTBLEED! Darn you to sock heck!).

Then use configupdate to set the OSP's TLS keystore to the right path, and the proper keystore password you just setup.

Trusted CA Certificates:

Make sure that the signing CA's and intermediate CA's that sign the SSL cert you requested are imported to the cacerts store for your JVM.

/opt/netiq/idm/apps/jre/bin/keytool -import -alias interCA -file /opt/netiq/idm/apps/tomcat/conf/intermediate.b64 -keystore /opt/netiq/idm/apps/tomcat/conf/tomcat.jks -trustcacerts


This is an important and subtle point, that the IDP's web page's SSL cert may differ from the IDP services SSL cert. That is, the SOAP conversation going on for auth in the backend, may have a different SSL cert (self signed, 20-30 years, etc) than the SSL cert on the front end that you login with, in which case make sure you have the signing CA's in cacerts as well, if they differ. Make sure that the eDirectory tree CA's public key is imported into the cacerts file as well as a trustcacerts, so that LDAPS will work without error.

Thus your cacerts file (or else your tomcat.jks file, so you do not lose the imported stuff when a JVM update happens) will hold trustedcacerts for:
     IDV tree CA (For LDAPS)
     Public CA that signs OSP, IDP, and Tomcat certs.

Finally you need one more cert, which is the public key of the certificate used by the IDP. That is, when OSP and IDP talk, they do an SSL key exchange, to do that, OSP has to trust whomever signed the IDP SSL cert. This is included in the metadata. You will find in the metadata the base64 encoded public key of the IDP's SSL cert. Copy the text, and paste it between lines that say:

-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

The metadata will have a block that looks like:

      <KeyDescriptor>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>base64StuffRedacted</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</KeyDescriptor>


Take everything between the open and close X509Certificate nodes.

Save that file as idp-cert.b64 then import it into the tomcat.jks keystore as a trusted cert as:

/opt/netiq/idm/apps/jre/bin/keytool -import -alias idp-cert -file /opt/netiq/idm/apps/tomcat/conf/idp-cert.b64 -keystore /opt/netiq/idm/apps/tomcat/conf/tomcat.jks -storepass novell -trustcacerts


That is all simple, when you get down to it, but the details are kind of painful at times.

Next up, you need to deal with the IDP metadata. This is because OSP has a bug where it incorrectly reads the lines in the metadata:
<SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://login.acme.edu/idp/profile/Shibboleth/SSO" />
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://login.acme.edu/idp/profile/SAML2/POST/SSO" />
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://login.acme.edu/idp/profile/SAML2/POST-SimpleSign/SSO" />
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://login.acme.edu/idp/profile/SAML2/Redirect/SSO" />


OSP should find the HTTP-POST and use that URL to POST a message. However it seems to try to POST to the Redirect URL. It does this with NAM as well, clearly a bug, reported to be fixed.

In the short term, you can work around it by editing the URL value in HTTP-Redirect line, to be the URL from the HTTP-POST line (The Location attribute). This way, when it incorrectly tries to POST to the Redirect URL it will succeed, since it will now be sending to the POST URL. It turns out OSP itself (when acting as IDP) and NAM use the same endpoint URL for both POST and Redirect, so they do not see this as an issue normally.

Then save the edited Metadata file, and host it on a web server that OSP can get too, and specify that URL in ConfigUpdate as the SAML metadata URL. Thus you have extra step of editing the metadata, saving it, putting it on an accessible web server.

Once you have done this, OSP is configured for SAML federation with Shibboleth.

On the Shibboleth side, you need to provide a URL for your metadata, that OSP exposes. (It does not expose it, until you make the switch in Configupdate and restart Tomcat). This will be in the format of:
https://idmServ.acme.edu:8443/osp/a/idm/auth/saml2/spmetadata

They will import that into their system, which is how they add a federation partner. This should mean they import the certificate properly that your OSP SP uses.

There are two additional steps you need to ask your Shibboleth IDP admin to do for you.

1) Disable encryption in AuthNReponse.
2) Name attributes so that Name and FriendlyName are in LDAP name format.


1) Disable encryption in AuthNReponse.

The SAML conversation is inside an SSL message body and encrypted. But the IDP could respond with data it sends you, encrypted a second time inside it. OSP does not like this and it needs to be disabled. This is the code block the IDP needs:

<!-- idvault : do not require encryption. -->
<RelyingParty id="https://idmServr.acme.edu:8443/osp/a/idm/auth/saml2/metadata"
provider="https://login.acme.edu/idp/shibboleth"
defaultSigningCredentialRef="IdPCredential">
<ProfileConfiguration xsi:type="saml:SAML2SSOProfile" encryptAssertions="never" encryptNameIds="never" />
</RelyingParty>
<!-- END idvault -->



2) Name attributes so that Name and FriendlyName are in LDAP name format.

The attributes are sent in the SAML response. (Get SAML Tracer as a Firefox add on, and you can see it happen and see the AuthNRequest OSP sends, and the AuthNResponse that the IDP returns. In that return there are nodes that look like:

<saml2:Attribute FriendlyName="mail"
Name="urn:oid:0.9.2342.19200300.100.1.3"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsi:string">geoffc@acme.edu</saml2:AttributeValue>
</saml2:Attribute>


The problem is that OSP reads the Name="urn:oid:0.9.2342.19200300.100.1.3" for the attribute name. Which is NOT the mail, or cn that you entered in configupdate. Instead, the IDP needs to send your attribute with Name="mail" and FriendlyName="something". This takes two changes on the IDP side:

Add to attribute-resolver.xml

    <resolver:AttributeDefinition id="serialNumberOSP" xsi:type="Simple" xmlns="urn:mace:shibboleth:2.0:resolver:ad"
sourceAttributeID="serialNumber">
<resolver:Dependency ref="shib_attr" />
<resolver:AttributeEncoder xsi:type="SAML2String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
name="cn" friendlyName="serialNumber" />
</resolver:AttributeDefinition>



Change the attribute-filter.xml

<AttributeFilterPolicy id="idvaultdev3">
<PolicyRequirementRule xsi:type="basic:AttributeRequesterString"
value="https://idmServ.acme.edu:8443/osp/a/idm/auth/saml2/metadata" />
<AttributeRule attributeID="serialNumberOSP">
<PermitValueRule xsi:type="basic:ANY" />
</AttributeRule>
</AttributeFilterPolicy>


Once you do that, it started working for me. I was able to SSO to everything.

Now along the way I found stacks and stacks of issues, which I will try to write up in a separate article (series likely) that explains what broke and how I figured it out.

Labels:

How To-Best Practice
Comment List
Parents
  • The default name format for attributes published by the Shibboleth IdP is "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", hence the attribute names in the assertions that look like "urn:oid:0.9.2342.19200300.100.1.3" or "">www.incommon.org/.../attributesummary.html

    If you want to use a "friendly name" type name for the attribute's name, to stay syntactically correct, you need to change the name format to "urn:oasis:names:tc:SAML:2.0:attrname-format:basic", e.g.


    geoffc@acme.edu


    I don't think that the friendlyName and name attributes need to be different, but the should follow the nameFormat in the attribute definition.
Comment
  • The default name format for attributes published by the Shibboleth IdP is "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", hence the attribute names in the assertions that look like "urn:oid:0.9.2342.19200300.100.1.3" or "">www.incommon.org/.../attributesummary.html

    If you want to use a "friendly name" type name for the attribute's name, to stay syntactically correct, you need to change the name format to "urn:oasis:names:tc:SAML:2.0:attrname-format:basic", e.g.


    geoffc@acme.edu


    I don't think that the friendlyName and name attributes need to be different, but the should follow the nameFormat in the attribute definition.
Children
Related
Recommended