Apereo CAS - Import & Export w/ Service Registries

Posted by Misagh Moayyed on August 15, 2020 · 5 mins read ·
Content Unavailable
Your browser is blocking content on this website. Please check your browser settings and try again.

Apereo CAS offers a large menu of options for managing client application registration records. One popular option especially applicable to distributed deployments of the CAS server is to store application policies inside a relational database such as MySQL, Oracle, etc. In this use case, while CAS can be configured to automatically generate the necessary schemas and table structures required to manage application data, it might be challenging to properly import existing applications into the database or export the current dataset into a friendly format for reviews and audits. Rather than playing around with database native tooling or manually fiddling with fancy SQL statements, (a very-discouraged endeavor), the CAS server itself offers a few additional tools that allow one to import or export the contents of the service registry regardless of the type of storage service.

Our starting position is as follows:

Setup

The service management facilities in Apereo CAS can be controlled and massaged using several actuator endpoints. These endpoints, once exposed, secured and enabled, allow the adopter to peek into the current contents of the service registry, export entries as a zip file or import a pre-existing application policy file into the registry without having to deal with the specifics of the storage technology used by CAS.

For example, let’s imagine that a CAS server deployment is backed by a MySQL database to manage application policies. To start, we can verify the initial empty state of the service registry by invoking an actuator endpoint that reports back the registry contents:

curl -u casuser:Mellon https://sso.example.org/cas/actuator/registeredServices | jq 
Note
This post assumes that all CAS actuator endpoints are protected with basic auth using the predefined credentials casuser and Mellon for the username and password, respectively.

Next, let’s prepare a sample JSON file to represent an application registration record:

{
  "@class" : "org.apereo.cas.services.RegexRegisteredService",
  "serviceId" : "https://service.example.com/.*",
  "name" : "Service",
  "id" : 1,
  "evaluationOrder" : 10
}

To import the file into the CAS service registry, we can invoke yet another actuator endpoint that expects the body of the request to be our service definition:

curl -u casuser:Mellon -X POST -H "Content-Type: application/json" \
     --data-binary "@/path/to/Service-1.json" \
     https://sso.example.org/cas/actuator/importRegisteredServices

Of course, you could do the same if the application policy is a YAML file:

curl -u casuser:Mellon -X POST -H "Accept: application/vnd.cas.services+yaml" \
     --data-binary "@/path/to/Service-1.yaml" \
     https://sso.example.org/cas/actuator/importRegisteredServices
Note
The --data-binary flag is important for curl, since it preserves the formatting of line breaks allowing CAS to properly recognize the syntax and consume the content.

Once entries are imported, you can invoke the previous registeredServices actuator endpoint to peek at the content, or you could also ask for an export of the entire service registry as a zip file:

curl -u casuser:Mellon https://sso.example.org/cas/actuator/exportRegisteredServices -o results.zip

Need Help?

If you have questions about the contents and the topic of this blog post, or if you need additional guidance and support, feel free to send us a note and ask about consulting and support services.

So…

Remember that the strategies outlined in this guide apply to all types of technologies and services that can manage application definitions in Apereo CAS. They are not limited to relational databases, and should work all the same if your deployment uses MongoDb, Cassandra or any other technology as the backing solution for the CAS service registry.

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 know that all other use cases, scenarios, features, and theories certainly are possible as well. Feel free to engage and contribute as best as you can.

Happy Coding,

Misagh Moayyed