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. MongoDB is developed by MongoDB Inc., and is published under a combination of the Server Side Public License and the Apache License.
MongoDB 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 properties and settings. We will also try to reload settings dynamically in real-time as they are changed and updated inside MongoDB databases.
Our starting position is based on the following:
6.0.0-RC4
master
branch specifically)jq
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"]})
When ready, point your browser to http://localhost:8081
and let’s create a few documents with CAS settings in them. MongoDb documents are required to be found in the collection MongoDbProperty
, as the following document:
{
"id": "...",
"name": "the-setting-name",
"value": "the-setting-value"
}
So I am going to create a MongoDB database called cas
inside which the MongoDbProperty
needs to be created. Next, each of the below settings will be housed inside an indibidual MongoDB document that matches the above JSON structure:
cas.authn.accept.users=casuser::MongoDB
management.endpoints.web.exposure.include=*
management.endpoints.enabled-by-default=true
cas.monitor.endpoints.endpoint.defaults.access=AUTHENTICATED
spring.security.user.name=casuser
spring.security.user.password=Mellon
The end result will look something like this:
You may also want to create an index on name
:
That should do for now. Let’s get CAS running.
Integration with MongoDB in CAS to manage configuration can be done in a number of ways:
If you have the Spring Cloud Config Server deployed, MongoDB could be one of its many sources for settings and properties. In this scenario, you will just need to make sure the CAS server can talk to the Spring Cloud Config Server correctly, and the Config Server is then in charge of communicating with MongoDB to fetch settings, etc.
Alternatively, you may decide to connect your CAS server directly to MongoDB and fetch settings. This is the approach we are going to try in this tutorial for a quick win, but do note that the strategy is almost the same if we were to use the Cloud Config server.
So in order to enable a CAS integration with MongoDB directly, you want to start with the CAS Overlay, clone the project and then put the following settings into a src/main/resources/bootstrap.properties
file:
spring.application.name=cas
spring.profiles.active=mongodb
cas.spring.cloud.mongo.uri=mongodb://casuser:Mellon@localhost:27017/cas
Of course, don’t forget to include the required module in your CAS build:
compile "org.apereo.cas:cas-server-support-configuration-cloud-mongo:${project.'cas.version'}"
Build and deploy. At this point, you should be able to log into CAS using casuser
and MongoDB
as the credentials!
If a setting changes, MongoDB has no way to broadcast the updated value(s) to its own clients, such as the CAS server itself. Therefore, in order to broadcast such change events, CAS presents various endpoints that allow the user to refresh the configuration as needed. This means that an adopter would simply change a required CAS setting and then would submit a request to CAS to refresh its current state. At runtime! All CAS internal components that are affected by the external change are quietly reloaded and the setting takes immediate effect, completely removing the need for container restarts or CAS re-deployments.
For example, start by changing the value of cas.authn.accept.users
in MongoDB to something like casuser::HelloWorld
. Then, execute the following command to refresh the CAS application context:
curl -k -u casuser:Mellon https://sso.example.org/cas/actuator/refresh -d {} -H "Content-Type: application/json"
...
["cas.authn.accept.users"]
At this point, you should be able to log into CAS using casuser
and HelloWorld
as the credentials!
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