Integrating ADFS (SAML) into Campus Solutions 9.2

Single Sign-On is becoming increasingly popular within the enterprise – with the reduction in monolithic systems design, users access a number of systems to perform discrete operations. Maintaining separate logons for each system is cumbersome and makes identity management almost impossible – for both users and IT departments.

Single Sign-On enables users to maintain a single identity (with an Identity Provider), with applications (Service Providers) trusting the Identity Provider to successfully authenticate the user and pass back the identity.

Single Sign-On supports many authentication types – if users are authenticated on the enterprise network (i.e. Active Directory), their identity can be determined through the SPNEGO / Kerberos protocols, or more generally through Integrated Windows Authentication – this process is invisible to the end user. Where this is not the case, the user must enter their credentials through a form-based authentication approach such as below (additionally, 2 factor authentication may also be configured as part of the authentication process within ADFS – ensuring consistent authentication approaches across the application estate).

This article explains how to integrate SAML based ADFS as the authentication mechanism for Campus Solutions 9.2. However, this will also be a useful resource when attempting to integrate ADFS into any web application.

How does Identity Provider ADFS work?

Identity Provider (IdP ) Initiated SSO is initiated by ADFS (the IdP) sending a SAML Response to a Service Provider. The main difference between IdP Initiated and Service Provider (SP) Initiated SSO is the triggering of the authentication process. With SP SSO, the application will generate a SAML Request when the user attempts to access the application and forward this (and the user) to ADFS – this allows the SP to track authentication requests from initiation to completion.

Ultimately, ADFS operates on a series of redirects and HTTP form submissions. The sequence diagram below outlines the process. ‘System’ is an application a user is trying to access that is protected by ADFS (i.e. Campus Solutions).

Before getting started with the implementation, it’s important to have a basic understanding of some of the key terms referred to throughout the rest of this article – they are explained below.

Deep Linking (Relay State)

When using IdP Initiated SSO, deep linking is achieved through the RelayState. The RelayState is a query parameter that is sent to ADFS by the application when the user is not authenticated. This RelayState is then sent back to application following successful ADFS authentication.

The RelayState can take any form – it can be a URL for simple redirects or it can be a base64 encoded JSON string if required (although be careful of URL lengths).

The RelayState is particularly useful for achieving Deep Linking – with IdP Initiated SSO, the users browser is always redirected back to the same application endpoint upon successfully authenticating with ADFS. It’s the RelayState also provided in the ADFS -> SP redirect which enables the application to redirect the user to their intended destination within the application.

In order to support Deep Linking, RelayState must be enabled in ADFS. Read this great blog for instructions on how to do so.

ADFS Session Cookie

The process of Single Sign-On is achieved through the use of an ADFS Session Cookie – once a user has successfully authenticated with ADFS, a cookie is set on the ADFS domain. The next time the user is sent to the ADFS authentication screen, the session cookie is sent along with the request – ADFS will check to ensure that the session has not expired and if it has not, will redirect the user to the appropriate application as if they had just successfully entered their login credentials.

Application Session Cookie

Similar in principle to the ADFS Session Cookie, the Application Session Cookie enables the application to remember users (i.e. whether they’ve previously logged on). It too may have an expiry – once expired, the user should be redirected to ADFS. If their ADFS session cookie is still active (i.e. ADFS Session Cookie Timeout > Application Session Cookie Timeout), the user will be redirected back to the application as per the ADFS Session Cookie example. If the ADFS Session Cookie is also no longer valid, the user will need to enter their username and password (plus any 2 factor) again.

ADFS Relying Party Configuration

This article is not intended to go into detail on how to configure a Relying Party on ADFS – others have done much better than I could so I suggest you read articles such as this one from Microsoft.

Implementation

Given the knowledge of ADFS outlined above, the complexity that remains is the configuration of Campus Solutions to parse a SAML response, validate it came from the IdP and then set the Application Session Cookie against the user identified in the SAML response.

Campus Solutions

The following components must be configured within Campus Solutions to integrate with ADFS:

  • Web Profile (and associated Site in WebLogic)
  • Base64 Decoding
  • Sign-on PeopleCode (FuncLib)
  • Validation JAR

The interaction of these components is depicted in the diagram below.

Web Profile

The Web Profile is associated with a hosted Web Logic ‘website’ – it’s the context within which your users interact with Campus Solutions. It relates to the SSO process in a number of ways:

  • Runs sign-on people code as a very restricted public user
  • Determines what pages will be sent back to the users browser following authentication events (success, failure, etc.)

The first task is to create a Web Profile that will support ADFS SSO (you may want to keep a web profile that still supports Campus Solutions form authentication for administrators, etc.). Your authentication domain will likely match your Campus Solutions domain, i.e: sts.my-organisation.com or campus-solutions.my-organisation.com. If you encounter errors regarding CORS, your authentication and Campus Solutions domains may differ. Try adding both domains to the ‘Authorized Site’ section of the Web Profile configuration.

The next step is to set up the public user and allow public access to the Web Profile – this user will run the sign-on code, validating the SAML response and setting the user context based upon the subject within the SAML response.

Finally, the pages that should be returned following authentication events must be configured in the following way:

  • Signon Result Doc Page – update to signonresultdocredirect.html such that the original deep link in the RelayState can be returned to the user now they have successfully authenticated. This HTML is shipped with all Campus Solutions installs.
  • Signon Error Page – in our implementation, any authentication failure would result in the user being sent back to ADFS. We achieve this by sending the user to the signin page where they will be forwarded to ADFS.

Sign-on PeopleCode

The Sign-on PeopleCode has the responsibility of handling the authentication process – from deciding whether the user should be redirected to ADFS, to validating the SAML token and deciding what to do on success or failure. The full Sign-on PeopleCode can be found on GitHub – the below explains some of the key sections.

The first line of code that may look slightly strange is one that is trying to get a Java class called ADFSSAMLResponseValidator – as you may know, PeopleCode can be used to execute Java. In order to do so, a JAR file containing the required class(es) must be included within the classes directory of the server. More information can found here.

The call below loads a reference to the class into the &SAML_Validate variable. Read further down this article for details of the ADFSSAMLResponseValidator class.

&SAML_Validate = GetJavaClass("saml.saml.ADFSSAMLResponseValidator")

The result of the ADFS authentication process is a SAML Response being sent to the Service Provider authorization URL – this response can be retrieved from the request in PeopleCode using the below line of code.

&requestParameter = %Request.GetParameter("SAMLResponse");

The SAML Response is base64 encoded by ADFS – it must therefore be decoded. Details on how to do this can be found here. The below uses the Crypt library to decode the SAML Reponse.

&samlDecode = CreateObject("Crypt");
&samlDecode.Open("BASE64_DECODE");
&samlDecode.UpdateData(&requestParameter);
&decodeResult = &samlDecode.Result;

In order to check whether the SAML Response is valid – its signature must be recalculated and validated (see the SAML Validation section below). This is achieved through the below call to ValidateSAMLResponse (a method of the Java class loaded earlier), passing in the decoded XML string (the SAMLResponse).

&SAML_Valid = &SAML_Validate.GetInstance().ValidateSAMLResponse(&decodeResult);

In addition to ADFS returning the SAML Response, the Relay State is also returned as a form parameter. This is retrieved to redirect the user to the page they initially tried to visit before being sent off to ADFS.

&Redirect_URL = %Request.GetParameter("RelayState");

The call that is the point of the sign-on code, SetAuthenticationResult, sets the userId that is retrieved from the SAML Response (see the full code for details), and sets the ResultDocument to be the redirect URL. Campus Solutions now forwards this ResultDocument value to signonresultdocredirect.html (configured to do so as part of the Web Profile above) where the PS_TOKEN is returned in the HTTP response and set on the users browser; as the response is a 302, the user is also redirected accordingly.

SetAuthenticationResult( True, &userID, &Redirect_URL)

In our implementation, where the authentication is unsuccessful (i.e. there’s no SAML response or the SAML response is not valid), the user is sent back to the signin page which redirects them to ADFS.

Finally, the signon PeopleCode should be registered within Campus Solutions – it should be the only enabled signon PeopleCode function (can be seen below against sequence number 6).

That is all that is required to configure Campus Solutions to authenticate users against ADFS and further adopt SSO into your enterprise. The final section below details the SAML Validation JAR – a custom implementation that validates a SAML response against an ADFS metadata endpoint.

SAML Validation

Validating a SAML token is relatively straightforward – when the IdP returns a SAML response, it creates a hash of the response and signs that hash with a private key. When the SP receives the SAML response, it can validate the responses integrity by decrypting the signed hash (with a public key provided in the SAML response) and comparing it with a recalculated hash. If the values match, we can be sure the SAML response has not been changed since it was originally signed.

However, by using the public key in the SAML response, we can’t be sure where this key has come from. To ensure this message has come from the IdP – we retrieve the ADFS metadata from the relevant endpoint (typically something like https://server/FederationMetadata/2007-06/FederationMetadata.xml) and check that the public key provided in the SAML response is one owned by the IdP.

The Validation JAR I have created is available on GitHub – note that it makes use of the great OpenSAML library to validate the signature and retrieve endpoint metadata.

Conclusion

You’ll often hear people say Campus Solutions does not support ADFS – whilst it’s true that Campus Solutions does not natively support ADFS, it does provide the necessary means of configuring this integration. I hope that a future release of Campus Solutions does support ADFS natively – it’s the way all academic institutions I have worked at are heading and it would be a real negative of the product if integration required either 1) custom coding, or 2) the customer to be sponged by another third-party provider selling their wares.

If you’re struggling to integrate ADFS and Campus Solutions please do get in touch and I will endeavour to assist where I can.

17 thoughts on “Integrating ADFS (SAML) into Campus Solutions 9.2

    1. Hi Kalim, do you have any specific questions? Feel free to reach out to me on LinkedIn (linked above) if it’s easier to chat.

      Like

  1. Hi Simon,

    Thanks for your reply.

    we are planning to implement SSO with ADFS for Peopletools 8.57. Please advise if you can share me the compiled java class/jar file.

    Please advise if this should be deployed in App sever class folder or web server.

    Like

  2. Hi Simon,

    This is a very helpful guide. I am hoping to test this and having trouble compiling the java program to build the jar file (or class file?). The program is not able to find the apache libraries and the opensaml libraries. Do you have any information on what i could be doing wrong?

    Please help with how to build this java program. Thanks in advance!

    Like

    1. Hi,

      The project is a Maven project so you’ll need to use Maven to install the dependencies before building.

      Good luck!
      Simon

      Like

      1. Thanks Simon! I was able to build a .class file using Maven for the java code.
        I have copied that on the app. server.

        Would you be able to help me figure out what should the

        Identifier (Entity ID) and the Reply URL (Assertion Consumer Service URL) be?

        Thanks in advance!

        Like

      2. Hi Simon,

        Do you have libraries that built in java 8? ver 3.4.6 was on java 7 then next version 4.0.0 is already at java 11.

        javac saml/saml/ADFSSAMLResponseValidator.java
        saml/saml/ADFSSAMLResponseValidator.java:16: error: cannot access InitializationService
        import org.opensaml.core.config.InitializationService;
        ^
        bad class file: ./org/opensaml/core/config/InitializationService.class
        class file has wrong version 55.0, should be 52.0
        Please remove or make sure it appears in the correct subdirectory of the classpath.

        Thanks,

        Uly

        Like

  3. Hi Simon, Please advise on your signondocredirect html file. can we know how the user signon is redirected to adfs url.

    Like

  4. Thanks Simon for detailed description of each steps.
    Is this similar for SP initiated SSO where PeopleSoft acts as IDP?

    Like

  5. Hi Simon, We are planning to implement SP Initiated SSO similar to your approach. Instead redirecting to IDP SSO URL (IDP Initiated) in Signin.html, we are planning to write a SP Initiated (Authnrequest) in Sigin.html. Can you help us in Peoplesoft if SP Initiated triggers in Signin.html what will be the EntityID or Issue ID, since in browser all we can see is URL append with &cmd=login but signin.html is the one which triggers the authnrequest.

    Please help us to figure our on the EntityID or Issuer ID.

    Like

  6. Hi Simon, We are planning to implement SP Initiated SSO similar to your approach. Instead redirecting to IDP SSO URL (IDP Initiated) in Signin.html, we are planning to write a SP Initiated (Authnrequest) in Sigin.html. Can you help us in Peoplesoft if SP Initiated triggers in Signin.html what will be the EntityID or Issue ID, since in browser all we can see is URL append with &cmd=login but signin.html is the one which triggers the authnrequest.

    Please help us to figure our on the EntityID or Issuer ID.

    Like

  7. Hi Simon, great blog, we have implemented the SP initiated method, but we are getting CORS issue “CORS Origin “https://online..microsoftonline.com” not authorized” even though we added this site to Authorized site. Please help us how you resolved this issue.

    Like

Leave a comment