Saturday, October 3, 2015

Configure Shibboleth Idp to achieve Single Sign-on with Zendesk

1. Introduction

Shibboleth is standards-based, open source middleware software which provides web single sign-on across or within organizational boundaries. It allows sites to make informed authorization decisions for individual access of protected online resources in a privacy-preserving manner.
Shibboleth Identity Provider supports the SAML2 specification and is therefore ideal for use with Zendesk. This document will describe the steps required to configure Shibboleth 2.0 Identity Provider to achieve single sign-on with Zendesk.

2. Install Shibboleth IdP

The V2 Shibboleth Identity Provider is a standard Java web application based on the Servlet 2.4 specification and should run for the most part in any compatible servlet container. For this setup, I am going to use Apache Tomcat 7.

  • Install and configure Apache tomcat 7
  • Download the Shibboleth Identity Provider (V2.4.4) software package.
  • Unzip the archive and uncomment <security-constraint>, <login-config> tag from ${shibboleth-identityprovider-2.4.4}\src\main\webapp\WEB-INF\web.xml file.
  • Run install.bat script. The installation directory given during installation will be known as IDP_HOME throughout this document.



  • Register your domain name to 'C:\Windows\System32\drivers\etc\hosts' file eg: '127.0.0.1 idp.waheedtechblog.com'.
  • Add https port in all URLs present in '${IDP_HOME}\metadata\idp-metadata.xml' file i.e change all 'https://idp.waheedtechblog.com/idp/shibboleth' to 'https://idp.waheedtechblog.com:8443/idp/shibboleth'.
  • Skip this step if you have added 'idp.xml' file under '${tomcat}\conf\Catalina\localhost' directory as mentioned in step#1 or else copy '${IDP_HOME}\war\Idp.war' file to '${tomcat}\webapps' directory.
  • Start tomcat and verify it by accessing the URL: https://<HOSTNAME>:<PORT>/idp/profile/Status. If everything is working correctly, It will display a “ok page.


3. Configuring Zendesk


  • Login to your zendesk application and select 'Security' under 'Settings' tab.



  • Add SAML SSO URL as 'https://idp.waheedtechblog.com:8443/idp/profile/SAML2/Redirect/SSO'. You can find this URL in your '${IDP_HOME}\metadata\idp-metadata.xml' file as HTTP-Redirect URL.
  • Certificate fingerprint: Double click on '${IDP_HOME}\credentials\idp.crt' file and copy 'thumbprint' value from 'Details' tab. Don't forget to remove the spaces.
  • Remote Logout URL and IP Ranges are optional. Save it.

4. Configuring Shibboleth Idp

To support SSO, We need to modify many files of IdP.

4.1 Enable logging

Before configuring anything, we should enable LOG at level DEBUG so that we can easily find out the issue. The Identity Provider uses the Logback logging system and logging configuration is located at $IDP_HOME/conf/logging.xml.

Change logger and root level as DEBUG

<logger name="edu.internet2.middleware.shibboleth" level="DEBUG”>
<root level="DEBUG">
<appender-ref ref="IDP_PROCESS"/>
</root>


The file changes will be reflected with in 10 minutes without restarting the IdP and check idp-process.log file for any issue.


4.2 Configure Username/Password Authentication

Authentication handler supports authenticating users with a username (netid) and password.
Uncomment username/password login handler in ${IDP_HOME}/conf/handler.xml file

<ph:LoginHandler xsi:type="ph:UsernamePassword"
jaasConfigurationLocation="file://C:\idpV2.4.4/conf/login.config">
<ph:AuthenticationMethod>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</ph:AuthenticationMethod>
</ph:LoginHandler>


and Comment RemoteUser login handler


<!-- <ph:LoginHandler xsi:type="ph:RemoteUser">
<ph:AuthenticationMethod>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</ph:AuthenticationMethod>
</ph:LoginHandler> -->





Note: Sometimes Idp is not able to find out the login.conf file as mentioned in Username\password login handler. In such cases add one extra '/' in the file path i.e.                                 jaasConfigurationLocation="file:///C:\idpV2.4.4\conf\login.config" 

4.3. Add LDAP Login Module Specification

Add Ldap configuration for Authentication to ${IDP_HOME}/conf/login.conf file.

Uncomment and modified LdapLoginModule as per your local environment

edu.vt.middleware.ldap.jaas.LdapLoginModule required

ldapUrl="ldap://localhost:389"

base="dc=altisource,dc=com"
serviceUser="cn=Directory Manager"
serviceCredential="root123"
ssl="false"
subtreeSearch="true"
userFilter="uid={0}";

Where

ldapUrl: url of the ldap where it is running
base: location where you have actually stored username/password (Base DN)
serviceUser: Administrative users using which you connect to Ldap
serviceCredential: Password of the ldap


This is how my Ldap Connection looks like



4.4 Add Zendesk metadata to IdP

The Shibboleth IdP must know some basic information about the Zendesk relying party, which is defined in SAML metadata. Create new IDP_HOME/metadata/zendesk-metadata.xml file with the following contents. There is much more information that could be added here, but this is the minimum required to get things working and replace YOURDOMAIN with the domain you have setup in Zendesk.

<?xml version="1.0" encoding="UTF-8"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
validUntil="2015-10-03T12:10:16Z"
cacheDuration="PT1444306216S"
entityID="YOURDOMAIN.zendesk.com">
<md:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://YOURDOMAIN.zendesk.com/access/saml"
index="1" />
</md:SPSSODescriptor>
</md:EntityDescriptor>



4.5 Configure Relying Party (relying-party.xml)


  • Instruct Shibboleth how to behave when talking to Zendesk by defining a new RelyingParty element in ${IDP_HOME}/conf/relying-party.xml. The following snippet should be added just after the DefaultRelyingParty element. Change the id and provider value as per your configuration.

<!-- relying party for zendesk -->
<rp:RelyingParty id="https://YOURDOMAIN.zendesk.com"
provider="https://idp.waheedtechblogsso.com:8443/idp/shibboleth"
defaultSigningCredentialRef="IdPCredential">
<rp:ProfileConfiguration xsi:type="saml:SAML2SSOProfile" encryptAssertions="never" encryptNameIds="never" signResponses="never" />
</rp:RelyingParty>



  • Add the following snippet to configure new metadata (zendesk-metadata.xml) file you have created earlier.

<!-- zendesk Metadata -->
<metadata:MetadataProvider id="IdPSP" xsi:type="metadata:FilesystemMetadataProvider"
metadataFile="c:\\idpV2.4.4\\metadata\\zendesk-metadata.xml" >
</metadata:MetadataProvider> 





  • Change encryptAssertions="conditional" to encryptAssertions="never " in 'SAML2SSOProfile' 

<rp:ProfileConfiguration xsi:type="saml:SAML2SSOProfile" includeAttributeStatement="true"
assertionLifetime="PT5M" assertionProxyCount="0"
signResponses="never" signAssertions="always"
encryptAssertions="never" encryptNameIds="never"
includeConditionsNotBefore="true"/>





4.6 Configure Attribute Resolver (attribute-resolver.xml)

Zendesk expects the email of the user logging in to be passed as the SAML Name Identifier. Shibboleth’s attribute resolver must be configured to make this data available by modifying ${IDP_HOME}/conf/attribute-resolver.xml.

Uncomment and modify Ldap data connector


<resolver:DataConnector id="openDJ" xsi:type="dc:LDAPDirectory" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
ldapURL="ldap://localhost:389"
baseDN="dc=domain, dc=com"
principal="cn=Directory Manager"
principalCredential="root123">
<dc:FilterTemplate>
<![CDATA[
(uid=$requestContext.principalName)
]]>
</dc:FilterTemplate>
<ReturnAttributes>mail cn</ReturnAttributes>
<LDAPProperty name="java.naming.ldap.attributes.binary" value="objectSid"/>
<LDAPProperty name="java.naming.referral" value="follow"/>
</resolver:DataConnector>




and then add the following attribute definition that was used to authenticate to the IdP.

<resolver:AttributeDefinition xsi:type="Simple" xmlns="urn:mace:shibboleth:2.0:resolver:ad" id="userEmailId" sourceAttributeID="mail">
<resolver:Dependency ref="openDJ" />
<resolver:AttributeEncoder xsi:type="enc:SAML2StringNameID" xmlns="urn:mace:shibboleth:2.0:attribute:encoder" nameFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" />
</resolver:AttributeDefinition>


<resolver:AttributeDefinition xsi:type="Simple" xmlns="urn:mace:shibboleth:2.0:resolver:ad" id="common_name" sourceAttributeID="cn">
<resolver:Dependency ref="openDJ" />
<resolver:AttributeEncoder xsi:type="enc:SAML2StringNameID" xmlns="urn:mace:shibboleth:2.0:attribute:encoder" name="common_name" />
</resolver:AttributeDefinition>





4.7 Configure Attribute Filter (attribute-filter.xml )

Finally, configure the Shibboleth attribute filtering engine to release the principal attribute (encoded as a NameID) to Zendesk. Add the following XML snippet to ${IDP_HOME}/conf/attribute-filter.xml alongside the existing policy elements.

<afp:AttributeFilterPolicy id="releaseTransientIdToAnyone">
<afp:PolicyRequirementRule xsi:type="basic:ANY"/>
<afp:AttributeRule attributeID="userEmailId">
<afp:PermitValueRule xsi:type="basic:ANY"/>
</afp:AttributeRule>

<afp:AttributeRule attributeID="common_name">
<afp:PermitValueRule xsi:type="basic:ANY"/>
</afp:AttributeRule>
</afp:AttributeFilterPolicy>



5. Verification

If everything goes well, our Shibboleth Idp should authenticate users to zendesk application.
Let's access zendesk domain: https://waheedtechblogsso.zendesk.com


It will redirect to Shibboleth Idp page for user credential




Once you entered the credential, it will redirect back to zendesk home page. (Just make sure you have the same credential in LDAP that you have used in zendesk to register it.)





Congratulation ...!!!