Apereo CAS - SAML2 Metadata with MongoDb


Collaborate
The 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.

MongoDB is a free and open-source cross-platform document-oriented database program. Classified as a NoSQL database program, MongoDB uses JSON-like documents with schemata and is supported in CAS in many different ways. In this walkthrough, we are going to take a pass at getting CAS connected to MongoDB to store SAML2 identity provider and service provider metadata documents.

Our starting position is based on the following:

MongoDB

To run MongoDB for development and testing, we can use the provided Docker image:

docker run -d -p 27017:27017 -e MONGO_INITDB_ROOT_USERNAME=root \
  -e MONGO_INITDB_ROOT_PASSWORD=secret --name="mongodb-server" mongo:4.0-xenial
docker ps

This runs a MongoDB database server which is useful for development but SHOULD NOT be used in production.

To access the MongoDB instance using a UI, run:

docker run --link mongodb-server -d -p 8081:8081 \
  -e 'ME_CONFIG_MONGODB_ADMINUSERNAME=root' \
  -e 'ME_CONFIG_MONGODB_ADMINPASSWORD=secret' \
  -e 'ME_CONFIG_MONGODB_SERVER=mongodb-server' mongo-express

The ME_CONFIG_MONGODB_SERVER is the address of the docker container that runs the MongoDB server. By default, Docker containers use the container as the DNS host name. So we can just specify the mongodb-server the name of the container that runs our MongoDB instance.

Shell into the container:

CID=docker ps -aqf name=mongodb-server
docker exec -it $CID /bin/bash

When inside the container:

mongo --host mongodb://root:secret@localhost:27017
use database cas;

# Create a database user for authentication
db.createUser({user:"casuser", pwd:"Mellon", roles: ["readWrite", "dbAdmin"]})

Point your browser to http://localhost:8081 and let’s create a collection called cas-saml-sp-metadata with the following document:

image

Note the value field which contains a base64-encoded version of the metadata for a SAML2 service provider which makes it easier to get the metadata added to the MongoDB document. I am also skipping over the metadata signature that would have been used to validate its integrity and that could have just as easily been added to the document using a signature field.

That should do for now. Let’s get CAS running.

CAS

SAML2 Service Provider Metadata

So in order to enable a CAS integration with MongoDB directly, you want to start with the CAS Overlay, clone the project and follow the notes here to get CAS acting as SAML2 identity provider. In its simplest form, it comes to down to the following settings:

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

…and this module in the CAS build:

compile "org.apereo.cas:cas-server-support-saml-idp:${project.'cas.version'}"

To keep things simple, we could use the JSON service registry to manage our SAML2 service provider definitions. Here is what our service definition might look like for SAML2 service provider in a SAML-1.json file:

{
  "@class" : "org.apereo.cas.support.saml.services.SamlRegisteredService",
  "serviceId" : "<your-sp-entity-id>",
  "name" : "SAML",
  "id" : 1,
  "description" : "This SP has its metadata in MongoDB somewhere.",
  "metadataLocation" : "mongodb://"
}

The metadata location in the registration record above simply needs to be specified as mongodb:// to signal to CAS that SAML metadata for our service provider must be fetched from MongoDB data sources defined in CAS configuration. As the next step, let’s teach CAS about our MongoDB setup. Just like before, you’d need this module in your CAS build:

compile "org.apereo.cas:cas-server-support-saml-idp-metadata-mongo:${project.'cas.version'}"

…and CAS needs to know how to connect to MongoDB to fetch stuff:

cas.authn.samlIdp.metadata.mongo.host=localhost
cas.authn.samlIdp.metadata.mongo.port=27017
cas.authn.samlIdp.metadata.mongo.userId=casuser
cas.authn.samlIdp.metadata.mongo.password=Mellon
cas.authn.samlIdp.metadata.mongo.collection=cas-saml-sp-metadata
cas.authn.samlIdp.metadata.mongo.databaseName=cas

That’s it. Build and run CAS. At this point, you should be able to log into service provider successfully whose metadata is fetched and processed by CAS from MongoDB.

SAML2 Identity Provider Metadata

If you examine your CAS startup logs, you might notice the following statement:

[...FileSystemSamlIdPMetadataLocator] - <Metadata directory location is at [/etc/cas/config/saml]>

…which matches our setting above:

cas.authn.samlIdp.metadata.location=file:/etc/cas/config/saml

Metadata artifacts that belong to CAS as a SAML2 identity provider may also be managed and stored via MongoDb. This includes things such as the metadata XML document, signing and encryption keys, etc. While CAS has the ability to generate brand new metadata in MongoDB, let’s instead figure out how our existing metadata might be relocated to MongoDB.

Let’s create a MongoDB collection called saml-idp-metadata in our cas database to hold IdP artifacts with the following document in it:

{
    "signingCertificate": "...",
    "signingKey": "...",
    "encryptionCertificate": "...",
    "encryptionKey": "...",
    "metadata": "..."
}

Here is the drill:

  • The metadata, signing and encryption certificates may be base64-encoded.
  • The signing and encryption keys MUST be signed and encrypted using CAS crypto settings and keys.

The signing secret key and the encryption secret key are both JWKs of size 512 and 256. We can use the command-line shell to create the two keys:

cas> generate-key key-size 512
$signingKey
cas> generate-key key-size 256
$encryptionKey

Once you have the keys, you can try to secure the metadata keys:

cas> cipher-text file /etc/cas/config/saml/idp-signing.key signing-key $signingKey encryption-key $encryptionKey
...
cas> cipher-text file /etc/cas/config/saml/idp-encryption.key signing-key $signingKey encryption-key $encryptionKey
...

The signing and encryption SAML2 metadata keys plus the base64-encoded versions of the signing and encryption certificates and the metadata XML can next be put into the MongoDB document.

image

CAS settings will then take on the following form:

# cas.authn.samlIdp.metadata.location=file:/etc/cas/config/saml
cas.authn.samlIdp.metadata.mongo.idpMetadataCollection=saml-idp-metadata
cas.authn.samlIdp.metadata.mongo.crypto.encryption.key=$encryptionKey
cas.authn.samlIdp.metadata.mongo.crypto.signing.key=$signingKey

Build and run CAS. At this point, you should be able to log into the service provider successfully with CAS using its own SAML2 metadata from MongoDB to produce a SAML2 response, etc.

Finale

I hope this review was of some help to you and I am sure that both this post as well as the functionality it attempts to explain can be improved in any number of ways. Please feel free to engage and contribute as best as you can.

Misagh Moayyed

Related Posts

CAS 6.0.0 RC4 Feature Release

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

Apereo CAS 6.0.x - Building CAS Feature Modules

An overview of how various CAS features modules today can be changed and tested from the perspective of a CAS contributor working on the codebase itself to handle a feature request, bug fix, etc.

CAS 6.0.x Deployment - WAR Overlays

Learn how to configure and build your own CAS deployment via the WAR overlay method, get rich quickly, stay healthy indefinitely and respect family and friends in a few very easy steps.

Apereo CAS - Jib at CAS Docker Images

Learn how you may use Jib, an open-source Java containerizer from Google, and its Gradle plugin to build CAS docker images seamlessly without stepping too deep into scripting Dockerfile commands.

Apereo CAS 6 - Administrative Endpoints & Monitoring

Gain insight into your running Apereo CAS 6 deployment in production. Learn how to monitor and manage the server by using HTTP endpoints and gather metrics to diagnose issues and improve performance.

Apereo CAS - Slurp Configuration with Groovy

Learn how CAS configuration may be consumed via Groovy to simplify and consolidate settings for multiple deployment environments and profiles.

Apereo CAS - Configuration Management with MongoDb

CAS distributed configuration management using MongoDb, where you learn how to store and secure CAS configuration settings and properties inside MongoDb.

Apereo CAS - Integration with HashiCorp Vault

CAS distributed configuration management using HashCorp Vault, where you learn how to store and secure CAS configuration settings and properties inside Vault.

CAS 6.0.0 RC3 Feature Release

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

Why you should choose CAS as your SSO system

Discover the true reasons to use CAS