Install CAS Server With DB Authentication

Reza Fathi
The Startup
Published in
7 min readSep 18, 2020

I’ve recently installed the Apereo CAS server for a project based on the spring boot. I didn’t find any good tutorial which shows the step-by-step process to install and config it. All the tutorials were old and vague. Also, the main documentation is very confusing. I’ve spent a lot of hours to figure out how to install and config it. At this tutorial, I’m going to show you all the things you need to install and config the CAS server to use a DB as a user source. I’ll also show you how to integrate the CAS on your services based on spring boot (part 2).

What is CAS server:

If you have ever logged into Google services such as Gmail, Youtube, and etc, you maybe have noticed if you logged into one service, you will be logged-in to all others too. How this is possible?

This is an SSO (Single-Sign-On) system. A method which lets the users to login to a group of services centrally in one place. Apereo CAS (Central Authentication Service) is an open-source project which provides you an easy way to implement SSO. It means your users can login/logout to all of your services centrally at the CAS just once, then they will have access to all the secure services without using the username/password.

How to start:

To install CAS you can use a method called “War Overlay”.

“Overlays are a strategy to combat repetitive code and/or resources. Rather than downloading the CAS codebase and building from source, overlays allow you to download a pre-built vanilla CAS web application server provided by the project itself and override/insert specific behavior into it. At build time, the build installation process will attempt to download the provided binary artifact first. Then the tool will locate your configuration files and settings made available inside the same project directory and will merge those into the downloaded artifact in order to produce one wholesome archive (i.e. cas.war) .”

But before this, you need some requirements to run CAS:

  • Java — You need JDK 11+, Install if it’s not installed before and set JAVA_HOME to where Java has been installed (for ubuntu you can check this useful article)
  • Git — You need git to clone the CAS overlay template, It’s not required, but I suggest to use it.

Now you should clone this Github repository somewhere on your system:

git clone https://github.com/apereo/cas-overlay-template

After cloning, to run CAS we need to config some essential things. Start by editing the cas.properties file at {project_root}/etc/cast/config folder. Set “cas.server.name” to localhost (https), and add “server.ssl.key-store” and “server.ssl.key-store-password”. We are going to create “thekeystore” file next.

cas.server.name=https://localhost:8443
cas.server.prefix=${cas.server.name}/cas
server.ssl.key-store=file:/etc/cas/config/thekeystore
server.ssl.key-store-password=changeit
logging.config=file:/etc/cas/config/log4j2.xml# cas.authn.accept.users=

Open a terminal and go to the {project_root}/etc/cas/config. Run this command and enter localhost for first and last name question:

keytool -genkey -keyalg RSA -alias thekeystore -keystore thekeystore -storepass changeit -validity 360 -keysize 2048

This command will create a “thekeystore” file. Please note to enter “localhost” for the first and last name to prevent SSL error for running the CAS management and other client apps. Now we need to import this file into the JDK to use for client apps. (Note to JAVA_HOME environment variable, you must have set it before)

keytool -importkeystore -srckeystore thekeystore -destkeystore $JAVA_HOME/lib/security/cacerts

After importing, you must restart all Java instances that are running or restart the system.

Next, install all the dependencies and build CAS (this command will copy configuration files from {project_root}/etc/cas/config to /etc/cas/config folder in your OS, make sure you have permission to create and write in this folder.)

./gradlew clean copyCasConfiguration build

Now you can run the CAS and test it. Just type in terminal:

./gradlew run

After seeing this,

Your CAS server is ready, you can access it at your local system: http://localhost:8443/cas/. Maybe you get an SSL error when open this URL. to ignore this error, in Chrome, when you are on the page, type “thisisunsafe”.

You can see the login page of the CAS. There is a default user that you can use to login. Enter “casuser” as the username and “Mellon” as the password.

Load Users from a DataBase:

CAS supports many different ways to authenticate users, for example, LDAP, X.509, Azure Active Directory, REST, Redis, Database, and many more. We are going to config a PostgreSQL DB as a source that will be used by CAS to authenticate the users.

To enable the Database authentication, we must add the following dependency to the war overlay. For this edit the {project_root}/build.gradle and add this line in the dependencies section (where there is this line “// Other CAS dependencies/modules may be listed here…”):

implementation "org.apereo.cas:cas-server-support-jdbc:${project.'cas.version'}"
implementation "org.apereo.cas:cas-server-support-jdbc-drivers:${project.'cas.version'}"

We need to create a table in postgres to store the user information. You can use this query to create the table for testing. We Also insert a user for the test (email/username: ‘user1@test.com’, password: ‘testpass’ which encoded by bcrypt algorithm)

CREATE TABLE users
(
id bigint NOT NULL,
disabled boolean,
email character varying(40) COLLATE pg_catalog."default",
first_name character varying(40) COLLATE pg_catalog."default",
last_name character varying(40) COLLATE pg_catalog."default",
expired boolean,
password character varying(100) COLLATE pg_catalog."default",
CONSTRAINT users_pkey PRIMARY KEY (id),
CONSTRAINT uk6dotkott2kjsp8vw4d0m25fb7 UNIQUE (email)
)
WITH (
OIDS = FALSE
);
INSERT INTO users(
id, disabled, email, first_name, last_name, expired, password)
VALUES (1, false, 'user1@test.com', 'test', 'user1', false, '$2y$12$7XQUDwK3QE7oBB0wmVpht.aT7gESI205SgWarj15Wz2Jt6OfglbQ.');

Connecting CAS to the Database is really simple and straightforward, we just need to add some configurations to our cas.properties. So edit {project_root}/etc/cas/config/cas.properties file and add these lines (we just edit the project cas.properties file, then we run gradlew command, it will be copied to /etc/cas/config folder automatically, so don’t edit /etc/cas/config files directly):

cas.authn.accept.users=
cas.authn.jdbc.query[0].driver-class=org.postgresql.Driver
cas.authn.jdbc.query[0].url=jdbc:postgresql://localhost:5432/{db-name}
cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.PostgreSQL95Dialect
cas.authn.jdbc.query[0].driver-class=org.postgresql.Driver
cas.authn.jdbc.query[0].user={db-username, default fo postgres is "postgres"}
cas.authn.jdbc.query[0].password={db-password, default for postgres is blank}
cas.authn.jdbc.query[0].sql=SELECT * FROM users WHERE email = ?
cas.authn.jdbc.query[0].password-encoder.type=BCRYPT
cas.authn.jdbc.query[0].field-password=password
cas.authn.jdbc.query[0].field-expired=expired
cas.authn.jdbc.query[0].field-disabled=disabled

Replace all the bold strings with your Database connection parameters. Please note to “cas.authn.jdbc.query[0].sql” config, it will be used to query the user by the username. Edit it based on your user’s table at the DB, for example, if you are using a username field, replace the email with the username. Also, you can specify the expired and disabled fields, they are the boolean fields in your user’s table which determine the user account is disabled/expired or not. If disabled/expired columns were true, CAS won’t let user login. Other important configs are password and password-encoder. You must set the field in your user table which stores the user password and let CAS know how the password is encoded. At this example, we are using the BCRYPT. You can see more options here.

There are more configurations you can use, please check this page for more information. Now you can build and run the CAS again (note it’s required to run copyCasConfiguration and build to install new dependencies and apply new configs):

./gradlew clean copyCasConfiguration build run

Now you can login with the test user, go to https://localhost:8443/cas and use ‘user1@test.com’ as username and ‘testpass’ as password.

Install CAS Management:

CAS management is an administrative interface for CAS. It is an independent software which you can deploy separately and lets you manage services and related configs. We are going to install and config it. First clone this repo:

git clone https://github.com/apereo/cas-management-overlay

Then you can config it by editing {project_root}/etc/cas/configs/management.properties file. It’s important to “set cas.server.name” to the URL of the CAS server.

cas.server.name=https://localhost:8443
cas.server.prefix=${cas.server.name}/cas
mgmt.serverName=https://localhost:8444
mgmt.adminRoles[0]=ROLE_ADMIN
mgmt.userPropertiesFile=file:/etc/cas/config/users.json
server.port=8444
server.ssl.key-store=file:/etc/cas/config/thekeystore
server.ssl.key-store-password=changeit
logging.config=file:/etc/cas/config/log4j2-management.xml

Because we are using the 8443 port for the CAS server, we must change the CAS management server to something else to avoid the port conflict. We set “mgmt.serverName” and “server.port” for this purpose.

There is a default user “casuser” at the users.json file. CAS Management will authenticate users by CAS server, so you need to map your user from the previous step at the users.json file. Change the “casuser” to “user1@test.com” (your defined user at the DB).

{
"user1@test.com" : {
"@class" : "org.apereo.cas.mgmt.authz.json.UserAuthorizationDefinition",
"roles" : [ "ROLE_ADMIN" ]
}
}

We also need to define the CAS management as a service in our CAS server. CAS management will be used to manage CAS services, but for now, we need to add it manually. We are going to config CAS to use json service registry to load and persist the services. There are many storage options for persisting the services for CAS server, you can find more information here.

Add a new dependency to “build.gradle” at CAS server overlay and also at “build.gradle” at CAS management overlay template:

implementation "org.apereo.cas:cas-server-support-json-service-registry:${project.'cas.version'}"

Add this config to the cas.properties:

cas.service-registry.json.location=classpath:/services

This config tells to CAS to load service information from {project_root}src/main/resources/services/ path. We are going to config CAS management to use the same path to manage services. Add this config to the CAS management config file:

cas.service-registry.json.location=file:/{path-to-src-folder-of-cas-overlay-template}/main/resources/services

To register the CAS management itself as a service add a new JSON file name “casManagement-1001.json” to {project_root}/src/main/resources/services path (create it if doesn’t exist) with the below content. (casManagement is the name of the service and 1001 is an ID for it, you should follow this naming convention: serviceName + “-” + serviceNumericId + “.json”)

{
"@class" : "org.apereo.cas.services.RegexRegisteredService",
"serviceId" : "https://localhost:8444/cas-management/",
"name" : "casManagement",
"id" : 1001,
"logoutType" : "BACK_CHANNEL",
"logoutUrl" : "https://localhost:8444/cas-management/logout"
}

build and run the CAS server and CAS management.

./gradlew clean copyCasConfiguration build run

Incommon.pem error:

When I was running CAS management on Ubuntu 18.04, I encountered to this error:

WARN [org.apereo.cas.support.saml.SamlUtils] — <Resource [class path resource [incommon.pem]] cannot be located> …

I’ve fixed this by adding incommon.pem file to {cas-management-root}/src/main/resources folder with this content.

Done…

CAS Management

It’s done for now. You can access to CAS management at https://localhost:8444/cas-management. There are many supported options and protocols you can use with CAS. Check documentation for more information. I’m going to use the CAS server for an example Spring Boot app in the next tutorial.

--

--