In this example project, some default cas config behaviours changed:
- ssl
keystore
location is underresources/config/ssl
. You may need to change or import keystore to your jdk's/lib/security/cacerts
. - log4j2 config is under
resources/config/logging
and default level is set towarn
. - service registry is under
resources/config/services
and a default is added.
An example working cas for a question about webflow decorations (https://groups.google.com/a/apereo.org/g/cas-user/c/pScwsrnyLTQ/m/bOf7a8tVBQAJ):
A smtp information needed for the problem to be seen(in the password changing screen) so you need to set up the fields in the application.yml file(a gmail smtp should work too):
spring:
mail:
test-connection: true
host: 'mail.myexample.com.tr'
port: 587
username: 'no-reply@myexample.com.tr'
password: 'smtppassword'
properties:
mail:
smtp:
auth: true
starttls:
enable: true
First change the user defined in
the InMemoryAuthnHandlerConfig.java,
change the demo
user's email for password reset instructions, you can use a temporary mail
from https://temp-mail.org
To run the example, run this command:
./gradlew run
to define a directory for log files and run the app in another profile(don't forget to change the yml file accordingly):
./gradlew run -DbaseDir=C:\\dev\\logs -Dspring.profiles.active=qa
go to https://localhost:8443/cas/login and use the given example user and password demo
with a
password of demo
A defined flow variable customData
, which has a method getRandomVideoSrc()
, that returns a
random video src as string, locations of webm files in
the resources/static/themes/customtheme/img
directory for web page to display a random video each time page loads.
customData
is working for the login
webflow as explained in the docs, but,
to make it work on logout, a setter method should be called in the configuration class. but
for pswdreset
webflow, i couldn't make it work. Here's the log on password change page.
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "customData.getRandomVideoSrc()" (template: "layout" - line 52, col 9)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1148) ~[spring-webmvc-5.3.22.jar!/:5.3.22]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1087) ~[spring-webmvc-5.3.22.jar!/:5.3.22]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.22.jar!/:5.3.22]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.22.jar!/:5.3.22]
... 41 more
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1011E: Method call: Attempted to call method getRandomVideoSrc() on null context object
Details:
From the WebFlowCustomDecorator.java file
//...
@Override
protected void doInitialize() {
// This works as explained in the docs. You'll see customData working in the main page and video element will be random on each refresh.
super.createFlowVariable(super.getLoginFlow(), "customData", WebFlowCustomData.class);
// This does not work
// super.createFlowVariable(super.getFlow("logout"), "customData", WebFlowCustomData.class);
// But if you register the logoutFlowDefinitionRegistry by calling the parent class's
// setLogoutFlowDefinitionRegistry method like done in the WebFlowConfig class,
// this code will register the variable in logout and you'll see that logoutFlow has the customData.
super.
createFlowVariable(super.getLogoutFlow(), "customData", WebFlowCustomData.class);
// This does now work either.
super.
createFlowVariable(super.getFlow("pswdreset"), "customData", WebFlowCustomData.class);
}
//...
Webm video files in the project are added from:
- https://github.com/projectivetech/media-samples/blob/master/sample.webm
- https://www.webmfiles.org/demo-files/
- https://file-examples.com/index.php/sample-video-files/sample-webm-files-download/
WAR Overlay Type: cas-overlay
- CAS Server
6.6.15.1
- JDK
11
To build the project, use:
# Use --refresh-dependencies to force-update SNAPSHOT versions
./gradlew clean build
To see what commands/tasks are available to the build script, run:
./gradlew tasks
If you need to, on Linux/Unix systems, you can delete all the existing artifacts (artifacts and metadata) Gradle has downloaded using:
# Only do this when absolutely necessary
rm -rf $HOME/.gradle/caches/
Same strategy applies to Windows too, provided you switch $HOME
to its equivalent in the above
command.
For the server to run successfully, you might need to create a keystore file.
This can either be done using the JDK's keytool
utility or via the following command:
./gradlew createKeystore
Use the password changeit
for both the keystore and the key/certificate entries.
Ensure the keystore is loaded up with keys and certificates of the server.
Extension modules may be specified under the dependencies
block of
the Gradle build script:
dependencies {
implementation "org.apereo.cas:cas-server-some-module"
...
}
To collect the list of all project modules and dependencies in the overlay:
./gradlew dependencies
On a successful deployment via the following methods, the server will be available at:
https://localhost:8443/cas
Run the server web application as an executable WAR. Note that running an executable WAR requires CAS to use an embedded container such as Apache Tomcat, Jetty, etc.
The current servlet container is specified as -tomcat
.
java -jar build/libs/cas.war
Or via:
./gradlew run
It is often an advantage to explode the generated web application and run it in unpacked mode. One way to run an unpacked archive is by starting the appropriate launcher, as follows:
jar -xf build/libs/cas.war
cd build/libs
java org.springframework.boot.loader.launch.JarLauncher
This is slightly faster on startup (depending on the size of the WAR file) than running from an unexploded archive. After startup, you should not expect any differences.
Debug the CAS web application as an executable WAR:
./gradlew debug
Or via:
java -Xdebug -Xrunjdwp:transport=dt_socket,address=5000,server=y,suspend=y -jar build/libs/cas.war
Run the CAS web application as a standalone executable WAR:
./gradlew clean executable
CDS is a JVM feature that can help reduce the startup time and memory footprint of Java
applications. CAS via Spring Boot
now has support for easy creation of a CDS friendly layout. This layout can be created by extracting
the CAS web application file
with the help of the tools
jarmode:
# Note:
# You must first build the web application with "executable" turned off
java -Djarmode=tools -jar build/libs/cas.war extract
# Perform a training run once
java -XX:ArchiveClassesAtExit=cas.jsa -Dspring.context.exit=onRefresh -jar cas/cas.war
# Run the CAS web application via CDS
java XX:SharedArchiveFile=cas.jsa -jar cas/cas.war
Deploy the binary web application file in build/libs
after a successful build to a servlet
container of choice.
To fetch and overlay a CAS resource or view, use:
./gradlew getResource -PresourceName=[resource-name]
You can use the overlay to construct the correct directory structure for custom inMemoryUser interface themes:
./gradlew createTheme -Ptheme=redbeard
The generated directory structure should match the following:
├── redbeard.properties
├── static
│ └── themes
│ └── redbeard
│ ├── css
│ │ └── cas.css
│ └── js
│ └── cas.js
└── templates
└── redbeard
└── fragments
HTML templates and fragments can be moved into the above directory structure, and the theme may be assigned to applications for use.
To list all available CAS views and templates:
./gradlew listTemplateViews
To unzip and explode the CAS web application file and the internal resources jar:
./gradlew explodeWar
- The
etc
directory contains the configuration files and directories that need to be copied to/etc/cas/config
.
./gradlew copyCasConfiguration
- The specifics of the build are controlled using the
gradle.properties
file.
Configuration metadata allows you to export collection of CAS properties as a report into a file that can later be examined. You will find a full list of CAS settings along with notes, types, default and accepted values:
./gradlew exportConfigMetadata
duct
is a Gradle task to do quick smoke tests of multi-node CAS high-availability deployments. In
particular, it tests correctness of ticket
sharing between multiple individual CAS server nodes backed by distributed ticket registries such as
Hazelcast, Redis, etc.
This task requires CAS server nodes to enable the CAS REST module. It will NOT work without it.
The task accepts the following properties:
- Arbitrary number of CAS server nodes specified via the
duct.cas.X
properties. - URL of the service application registered with CAS specified via
duct.service
, for which tickets will be requested. duct.username
andduct.password
to use for authentication, when requesting ticket-granting tickets.
It automates the following scenario:
- Authenticate and issue a service ticket on one CAS node
- Validate this service ticket on the another node
- Repeat (You may cancel and stop the task at any time with
Ctrl+C
)
If the task succeeds, then we effectively have proven that the distributed ticket registry has been set up and deployed correctly and that there are no connectivity issues between CAS nodes.
To run the task, you may use:
./gradlew duct
-Pduct.cas.1=https://node1.example.org/cas \
-Pduct.cas.2=https://node2.example.org/cas \
-Pduct.cas.3=https://node3.example.org/cas \
-Pduct.cas.4=https://node4.example.org/cas \
-Pduct.service=https://apereo.github.io \
-Pduct.username=casuser \
-Pduct.password=Mellon
You may also supply the following options:
duct.debug
: Boolean flag to output debug and verbose logging.duct.duration
: Number of seconds, i.e.30
to execute the scenario.duct.count
: Number of iterations, i.e.5
to execute the scenario.