Apereo CAS SAML Integration With ADFS


Collaborate
This blog is managed and hosted on GitHub. If you wish to update the contents of this post or if you have found an inaccuracy and wish to make corrections, we recommend that you please submit a pull request to this repository.

This is a short and sweet tutorial on how to integrate Apereo CAS, acting as a SAML identity provider, with ADFS.

Environment

CAS Configuration

In order to allow CAS to become a SAML2 identity provider, the overlay needs to be prepped based on the instructions provided here. Remember to add the relevant module to the overlay along with the list of required build repositories.

The SAML IdP configuration will need to minimally match the following settings:

cas.authn.samlIdp.entityId=https://cas.example.edu/idp
cas.authn.samlIdp.scope=example.edu
cas.authn.samlIdp.metadata.location=file:/etc/cas/saml

You will, of course, need to adjust your entityId and scope as needed. Upon startup, CAS will attempt to generate the appropriate metadata based on provided settings and produced artifacts will be placed at /etc/cas/saml. Of course, the running CAS process will need to have the right permissions in order to create this directory and the contents within it.

To keep things simple, we will also configure CAS to use LDAP authentication such that the established single sign-on session is based on the authenticated principal whose is based on the sAMAccountName attribute.

The ADFS instance needs to be registered with CAS as a service provider. You can choose a variety of service management options. For this tutorial, I will be using the JSON Service Registry with the following snippet as the ADFS registration record:

{
  "@class": "org.apereo.cas.support.saml.services.SamlRegisteredService",
  "serviceId": "http://adfs.example.edu/adfs/services/trust",
  "name": "adfs",
  "id": 10000007,
  "description": "adfs service",
  "logoutType": "NONE",
  "attributeReleasePolicy": {
    "@class": "org.apereo.cas.services.ReturnMappedAttributeReleasePolicy",
    "allowedAttributes": {
      "@class": "java.util.TreeMap",
      "upn": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn",
      "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname": "groovy { return 'DOMAIN\\\\' + attributes['username'][0] }"
    }
  },
  "requiredNameIdFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
  "metadataLocation": "/path/to/adfs-metadata.xml",
  "signAssertions": true,
  "signResponses": false
}

You certainly need to modify the serviceId and metadataLocation for your configuration but the most important bit in the above snippet is the blob that controls the allowedAttributes. The attribute release policy is essentially doing the following:

  • upn is released and mapped to the ADFS-required SAML name http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn.
  • http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountnwin is required by ADFS and is released here as a custom attribute. Since it requires a value in the format of DOMAIN\\username, this value is constructed via an inline groovy script, with each \ escaped with another \. Remember that username here is the name mapped to the attribute sAMAccountName that is retrieved from LDAP and is the CAS principal id. Also note that because all attributes in CAS are sort of treated and assumed to be multi-valued, we need to ensure that we grab the attribute value for username by indexing it with [0].

ADFS Configuration

Start with adding a Claims Provider Trust. In the screenshot below, ours is called CAS Login –TEST.

image

On the “Monitoring” tab, enter the URL of your CAS IdP metadata into the “Claims provider’s federation metadata URL:” field (i.e https://cas.example.edu/cas/idp/metadata).

image

On the “Identifiers” tab, enter a “Display name:” and enter the entity ID that you specified in your CAS IdP configuration into the ”Claims provider identifier” field (i.e. https://cas.example.edu/idp).

image

On the “Endpoints” tab, enter the endpoints for “SAML Single Sign-On Endpoints” and “SAML Logout Endpoints”. These can be found from your CAS IdP metadata. The first two values entered here are based on the “SingleSignOnService” bindings at the following endpoints:

  • https://cas.example.edu/cas/idp/profile/SAML2/POST/SSO
  • https://cas.example.edu/cas/idp/profile/SAML2/Redirect/SSO

The logout endpoint is based on the “SingleLogoutService” binding located at the following endpoint:

  • https://cas.example.edu/cas/idp/profile/SAML2/POST/SLO

image

To enable CAS only (ADFS will auto-redirect to CAS), run the following PowerShell command on the ADFS server:

Set-AdfsRelyingPartyTrust -TargetName "Microsoft Office 365 Identity Platform" -ClaimsProviderName "CAS Login - TEST"

To revert back to Active Directory, run the following PowerShell command on the ADFS server:

Set-AdfsRelyingPartyTrust -TargetName "Microsoft Office 365 Identity Platform" -ClaimsProviderName "Active Directory"

Summary

I hope this review was of some help to you. As you have been reading, I can guess that you have come up with a number of missing bits and pieces that would satisfy your use cases more comprehensively with CAS. In a way, that is exactly what this tutorial intends to inspire. Please feel free to engage and contribute as best as you can.

Misagh Moayyed

Related Posts

CAS 6.0.0 RC3 Feature Release

...in which I present an overview of CAS 6.0.0 RC3 release.

Apereo CAS - Multifactor Authentication with RADIUS

Learn how Apereo CAS may be configured to trigger multifactor authentication using a RADIUS server and its support for the Access-Challenge response type.

CAS Vulnerability Disclosure

Disclosure of a security issue with the MFA features.

CAS 6.0.0 RC2 Feature Release

...in which I present an overview of CAS 6.0.0 RC2 release.

Apereo CAS - dotCMS SAML2 Integration

Learn how to integrate dotCMS, a Content Management System and Headless CMS, with Apereo CAS running as a SAML2 identity provider.

Effective Software Troubleshooting Tactics

A collection of what hopefully are obvious troubleshooting tactics when it comes to diagnosing software deployment issues and configuration problems.

Apereo CAS - MaxMind Geo2IP ISP Integration

Learn how you may determine the Internet Service Provider, organization name, and autonomous system organization and number associated with the user's IP address in CAS using MaxMind services and present warnings in the authentication flow for the end-user if an IP address is matched.

Notes from Better by Design 2018

Be interested in humans and human success.

Apereo CAS - Authentication Lifecycle Phases

Tap into the Apereo CAS authentication engine from outside, and design extensions that prevent an unsuccessful authentication attempt or warn the user after-the-fact based on specific policies of your choosing.

CAS 6.0.0 RC1 Feature Release

...in which I present an overview of CAS 6.0.0 RC1 release.