CAS, being a Spring-Boot application at heart, includes a number of endpoints to help you monitor and manage the server when it’s pushed to production. You can choose to manage and monitor the deployment using HTTP endpoints, referred to as actuators. Such actuator endpoints can be secured in a variety of ways, the most common of which would be username/password via basic authentication. In this blog post, we will examine the security configuration of actuator endpoints secured whose access is controlled via a SQL database.
Our starting position is based on the following:
7.2.x
jq
Let’s begin with the premise that you have enabled and exposed the health
actuator endpoint. As the name suggests, this endpoint provides detailed information about the health of the CAS server. We will also mark the endpoint’s access rule as AUTHENTICATED
to disable anonymous access:
management.endpoint.health.enabled=true
management.endpoints.web.exposure.include=health
cas.monitor.endpoints.endpoint.health.access=AUTHENTICATED
At this point, if you attempt to access the health
endpoint,
curl https://sso.example.org/cas/actuator/health | jq
…you should see the following output:
{
"status": 401,
"error": "Unauthorized",
"message": "Unauthorized",
"path": "/cas/actuator/health"
}
So far, so good.
The AUTHENTICATED
access rule forces CAS, via Spring Security, to require authenticated requests via basic authentication. Therefore, we need to teach CAS about credential sources such as SQL databases that can validate credentials and report back the authentication result status, thereby allowing or refusing access. To enforce security, CAS takes advantage of Spring Security’s JDBC support to connect to a variety of databases, look up user information from different schemas and enforce access. The expected database schema would be as follows:
create table users(
username varchar_ignorecase(50) not null primary key,
password varchar_ignorecase(500) not null,
enabled boolean not null
);
create table authorities (
username varchar_ignorecase(50) not null,
authority varchar_ignorecase(50) not null,
constraint fk_authorities_users foreign key(username) references users(username)
);
create unique index ix_auth_username on authorities (username,authority);
The authority
column specifies the role assigned to the user. In our setup, accessing CAS actuator endpoints will require both a valid username/password AND an admin
authority or role assigned to the account.
Now, let’s configure CAS to talk to our database:
cas.monitor.endpoints.jdbc.driver-class=...
cas.monitor.endpoints.jdbc.ddl-auto=none
cas.monitor.endpoints.jdbc.dialect=...
cas.monitor.endpoints.jdbc.user=...
cas.monitor.endpoints.jdbc.password=...
cas.monitor.endpoints.jdbc.url=...
As discussed, we want to enforce ADMIN
level security before actuator endpoints are accessed:
spring.security.user.roles=ADMIN
cas.monitor.endpoints.jdbc.role-prefix=ROLE_
Finally, we need to instruct CAS to locate user accounts using a dedicated SQL query:
cas.monitor.endpoints.jdbc.query=SELECT * FROM USERS WHERE username = ?
…and for extra credit, we can instruct CAS to use a better hashing algorithm when it comes to decoding and validating passwords in our SQL table:
cas.monitor.endpoints.jdbc.password-encoder.type=DEFAULT
cas.monitor.endpoints.jdbc.password-encoder.encoding-algorithm=SHA-256
That is it! Now, when you attempt to access the health
actuator endpoint, your credentials with the right role should get you in:
curl -u casuser:M#ll0n https://sso.example.org/cas/actuator/health | jq
For this to work, you would need to make sure casuser
exists in the right tables with the right ADMIN
role/authority, and its corresponding password is properly encoded using SHA-256
.
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.
It’s important that you start off simple and make changes one step at a time. Once you have a functional environment, you can gradually and slowly add customizations to move files around.
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