An identity provider such as Apereo CAS that provides single sign-on is fully powered on once you begin to integrate and onboard applications to take advantage of centralized functionality and policy management. These applications, also known as services in the CAS vernacular, and their associated policies can be managed by a CAS deployment using a variety of services and technologies. The core component of the service/application management facility is what is referred to as the service registry that stores application definitions into an underlying store such as a relational database. Thus, the registry acts as a facade and gatekeeper between the business layers of the system and the storage facility that in our case happens to be an Oracle database.
In this tutorial, we will briefly take a look at JPA Service Registry support in CAS, with our starting position as follows:
6.2.x
Let’s take a look at our modest task list:
Let’s begin.
If you do have an Oracle database at hand, feel free to skip this step. I don’t happen to have one readily available so I decided to keep things simple by using a Docker container, off of a fairly sizeable Docker image, to power on an Oracle database instance:
docker run -d -p 1521:1521 --name oracle-db store/oracle/database-enterprise:12.2.0.1-slim
Be patient. It might some time for Docker to pull down the image and start the container, but once ready, you should see the following output:
$ docker ps
CONTAINER ID IMAGE PORTS NAMES
a42d53af19f5 store/oracle/database-enterprise:12.2.0.1-slim 0.0.0.0:1521->1521/tcp, 5500/tcp oracle-db
During the process, if you ever needed to start over fresh and spawn a new container, you may kill and remove all traces of the existing running container via the following bash function:
function dkc() {
export CID=$(docker ps -aqf "name=$1");
docker stop $CID 2>/dev/null
docker rm -f $CID 2>/dev/null
docker volume prune --force
}
…which allows you to simply pass along the container name as a function parameter to stop and remove the container:
dkc oracle-db
dkc
is short for Docker Kill Container. You're welcome to choose a more creative name!
So back to the task at hand, we will keep this container running in the background and will use it as a testbed to connect it to our CAS instance to store application registration records.
You should start by including the indicated module in your CAS WAR Overlay. Of course, we have to introduce CAS and our Oracle database to each other using the following settings:
cas.jdbc.showSql=true
cas.serviceRegistry.jpa.user=system
cas.serviceRegistry.jpa.password=Oradoc_db1
cas.serviceRegistry.jpa.driverClass=oracle.jdbc.driver.OracleDriver
cas.serviceRegistry.jpa.url=jdbc:oracle:thin:@localhost:1521:ORCLCDB
cas.serviceRegistry.jpa.dialect=org.hibernate.dialect.Oracle12cDialect
cas.serviceRegistry.jpa.ddlAuto=update
That should be all. Once you rebuild and run CAS again, you should see the following in the CAS logs:
INFO [o.a.c.s.AbstractServicesManager] - <Loaded [0] service(s) from [JpaServiceRegistry].>
In the above settings, we are instructing CAS to achieve the following:
SELECT
or DELETE
, etc.So at this point, we have a running CAS server talking to our Oracle database. However, as the log message above indicates, we have no services available in our registry so let’s populate our database instance by importing a few application definitions.
INSERT
statements; that has the potetial to corrupt the database state very quickly.
Based on the CAS documentation, our JPA service registry is able to auto initialize itself from default JSON service definitions available to CAS. The initializer can detect all service definitions files found on the classpath (i.e. src/main/resources/services
) and import them into the real service registry used. Note that the location of the JSON files, while typically set to the classpath, may be controlled via CAS properties; The same setting that controls the location of the JSON service files for the JSON service registry is used by the initialization logic to locate service files.
So let’s instruct CAS to initialize itself from JSON definitions that can be found in our given path:
cas.serviceRegistry.initFromJson=true
cas.serviceRegistry.json.location=file:/etc/cas/config/services
Our /etc/cas/config/services
directory should contain the following files to be importted:
$ ls /etc/cas/config/services
Permissions Size User Group Date Modified Name
.rw-r--r-- 488 Misagh wheel 30 Sep 2019 Sample-100.json
Our Sample-100.json
file as an example contains the following:
{
"@class": "org.apereo.cas.services.RegexRegisteredService",
"serviceId": "https://mmoayyed.example.net:9443/sample.*",
"name": "Sample",
"id": 100,
"description": "Sample Java CASified application"
}
If you build and run CAS again, you should see the following output in your CAS logs:
INFO [o.a.c.c.CasServiceRegistryInitializationConfiguration] - <Attempting to initialize the service registry \
[EmbeddedResourceBasedServiceRegistry,JpaServiceRegistry] from service definition resources \
found at [URL [file:/etc/cas/config/services]]>
...
...
<Loaded [2] service(s) from [EmbeddedResourceBasedServiceRegistry,JpaServiceRegistry].>
While the above output may be somewhat cryptic, what it’s saying is that two service registries are active:
EmbeddedResourceBasedServiceRegistry
which is mainly responsible for loading our service definitions and preparing them for import.JpaServiceRegistry
which is the real registry and the target destination for the import operation.From here on out, JpaServiceRegistry
will be regarded as the main service registry. To confirm the import, you can always double-check the state of the database:
Of course, remember to turn off or remove the below settings when you’re done:
# cas.serviceRegistry.initFromJson=true
# cas.serviceRegistry.json.location=file:/etc/cas/config/services
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.
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.
Monday-Friday
9am-6pm, Central European Time
7am-1pm, U.S. Eastern Time
Monday-Friday
9am-6pm, Central European Time