Skip to content

Add sample CAS app with java configuration #121

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,4 @@ gradle-app.setting

# End of https://www.toptal.com/developers/gitignore/api/gradle,java,intellij,eclipse

/servlet/java-configuration/cas/install-cas/cas-server
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version=6.0.0-SNAPSHOT
version=6.1.0-SNAPSHOT
org.gradle.jvmargs=-Xmx3g -XX:+HeapDumpOnOutOfMemoryError
org.gradle.parallel=true
org.gradle.caching=true
54 changes: 54 additions & 0 deletions servlet/java-configuration/cas/install-cas/install-cas.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/bin/bash
#
# Copyright 2023 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
jq -h > /dev/null 2>&1
if [[ $? -ne 0 ]]; then
echo jq not installed
exit 1
fi
curl -h > /dev/null 2>&1
if [[ $? -ne 0 ]]; then
echo curl not installed
exit 1
fi

INSTALL_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
command -v cygpath > /dev/null && test ! -z "$MSYSTEM"
if [[ $? -eq 0 ]]; then
INSTALL_DIR=$(cygpath -w "$INSTALL_DIR")
fi
# The supported version of CAS in the cas initializr changes over time so query the current value (for 6.6.x)
# Get valid combinations with this: curl -s https://casinit.herokuapp.com/actuator/info/ | jq '."supported-versions"[] | select(.branch == "6.6")'
CAS_VERSION=$(curl -s https://casinit.herokuapp.com/actuator/info/ | jq -r '."supported-versions"'[2].version)
BOOT_VERSION=$(curl -s https://casinit.herokuapp.com/actuator/info/ | jq -r '."supported-versions"'[2].bootVersion)
set -e
SERVER_DIR=${INSTALL_DIR}/cas-server
mkdir -p $SERVER_DIR
cd $SERVER_DIR
curl https://casinit.herokuapp.com/starter.tgz -d "dependencies=support-json-service-registry&casVersion=${CAS_VERSION}&bootVersion=${BOOT_VERSION}" | tar -xzvf -
echo Building cas server
./gradlew build
mkdir -p ./etc/cas/config

echo Service Directory is ${INSTALL_DIR}/services
DEBUG=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5555

java $DEBUG -jar build/libs/cas.war \
--cas.standalone.configuration-directory=./etc/cas/config \
--server.ssl.enabled=false \
--server.port=8090 \
--cas.service-registry.core.init-from-json=false \
--cas.service-registry.json.location=file:${INSTALL_DIR}/services
39 changes: 39 additions & 0 deletions servlet/java-configuration/cas/install-cas/run-cas-docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash
#
# Copyright 2023 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
docker --version > /dev/null 2>&1
if [[ $? -ne 0 ]]; then
echo docker not installed
exit 1
fi
INSTALL_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
command -v cygpath > /dev/null && test ! -z "$MSYSTEM"
if [[ $? -eq 0 ]]; then
INSTALL_DIR=$(cygpath -w "$INSTALL_DIR")
fi

CAS_VERSION=6.6.6
# Note that the default apereo/cas image doesn't contain the modules you will need
# You need to start with an cas overlay template and build your own image with the modules you want to use.
# See https://github.com/apereo/cas-overlay-template or https://github.com/apereo/cas-initializr
docker run -d -p 8090:8080 --name cas -v $INSTALL_DIR/services:/etc/cas/services --rm apereo/cas:$CAS_VERSION \
--cas.standalone.configuration-directory=/etc/cas/config \
--server.ssl.enabled=false \
--server.port=8080 \
--cas.service-registry.core.init-from-json=false \
--cas.service-registry.json.location=file:/etc/cas/services

docker logs cas -f
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"@class": "org.apereo.cas.services.CasRegisteredService",
"serviceId": "^(https?)://.*",
"name": "HTTP/HTTPS",
"id": 1,
"description": "This service definition authorizes all application urls that support HTTP and HTTPS protocols.",
"evaluationOrder": 10000
}
18 changes: 18 additions & 0 deletions servlet/java-configuration/cas/install-cas/stop-cas-docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash
#
# Copyright 2023 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

docker stop cas
68 changes: 68 additions & 0 deletions servlet/java-configuration/cas/login/README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
= CAS Login & Logout Sample

This guide provides instructions on setting up an application that uses the CAS protocol for login.
It uses https://casserver.herokuapp.com/cas/login as the server supporting the CAS protocol.

The sample application uses Spring Boot and the `spring-security-cas`.

== Goals

=== CAS Login

`cas/login` provides a very simple implementation of a CAS Service (application) that use a public test CAS server for
authentication.

The following features are implemented in the MVP:

1. Login
2. Logout

== Run the Sample

=== Start up the Sample Application in Tomcat with Gretty
[source,bash]
----
./gradlew :servlet:java-configuration:cas:login:appRun
----

=== Open a Browser

https://localhost:8443/

You will be redirect to a sample CAS server: https://casserver.herokuapp.com/cas

=== Type in the credentials

[source,bash]
----
User: casuser
Password: Mellon
----

=== Run a local CAS server
Run the following script to install and start a CAS server that responds at http://localhost:8090/cas/login

[source,bash]
----
servlet/java-configuration/cas/install-cas/install-cas.sh
----
or with Docker:
[source,bash]
----
servlet/java-configuration/cas/install-cas/run-cas-docker.sh
----

Adjust the `servlet/java-configuration/cas/login/src/main/resources/security.properties` file to point at local CAS server:

[source,bash]
----
cas.base.url=http://localhost:8090/cas
cas.login.url=http://localhost:8090/cas/login
----

Then run the CAS login app in gretty and browse to https://localhost:8443.

[source,bash]
----
./gradlew :servlet:java-configuration:cas:login:appRun
----
65 changes: 65 additions & 0 deletions servlet/java-configuration/cas/login/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

plugins {
id "java"
id "nebula.integtest" version "8.2.0"
id "org.gretty" version "4.0.3"
id "war"
}

apply from: "gradle/gretty.gradle"

repositories {
mavenLocal()
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://build.shibboleth.net/nexus/content/repositories/releases/" }
}

dependencies {
implementation platform("org.springframework:spring-framework-bom:6.0.5")
implementation platform("org.springframework.security:spring-security-bom:6.1.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0")

implementation "org.springframework.security:spring-security-config"
implementation "org.springframework.security:spring-security-web"
implementation "org.springframework:spring-webmvc"
implementation "org.springframework.security:spring-security-cas"
implementation "org.thymeleaf:thymeleaf-spring6:3.1.0.M1"
implementation "org.thymeleaf.extras:thymeleaf-extras-springsecurity6:3.1.0.M1"

implementation 'ch.qos.logback:logback-classic:1.4.5'

providedCompile "jakarta.servlet:jakarta.servlet-api:6.0.0"
providedCompile "org.glassfish.web:jakarta.servlet.jsp.jstl:2.0.0"

testImplementation "org.assertj:assertj-core:3.18.0"
testImplementation "org.springframework:spring-test"
testImplementation "org.springframework.security:spring-security-test"
testImplementation("org.junit.jupiter:junit-jupiter-api")
testImplementation "org.seleniumhq.selenium:htmlunit-driver:3.64.0"
testImplementation 'org.hamcrest:hamcrest:2.2'
testImplementation 'org.awaitility:awaitility:4.2.0'

testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
}

tasks.withType(Test).configureEach {
useJUnitPlatform()
outputs.upToDateWhen { false }
}
42 changes: 42 additions & 0 deletions servlet/java-configuration/cas/login/gradle/gretty.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
gretty {
servletContainer = "tomcat10"
contextPath = "/"
fileLogEnabled = false
integrationTestTask = 'integrationTest'
httpsEnabled = true
}

Task prepareAppServerForIntegrationTests = project.tasks.create('prepareAppServerForIntegrationTests') {
group = 'Verification'
description = 'Prepares the app server for integration tests'
doFirst {
project.gretty {
httpPort = -1
}
}
}

project.tasks.matching { it.name == "appBeforeIntegrationTest" }.all { task ->
task.dependsOn prepareAppServerForIntegrationTests
}

project.tasks.matching { it.name == "integrationTest" }.all {
task -> task.doFirst {
def gretty = project.gretty
String host = project.gretty.host ?: 'localhost'
boolean isHttps = gretty.httpsEnabled
Integer httpPort = integrationTest.systemProperties['gretty.httpPort']
Integer httpsPort = integrationTest.systemProperties['gretty.httpsPort']
int port = isHttps ? httpsPort : httpPort
String contextPath = project.gretty.contextPath
String httpBaseUrl = "http://${host}:${httpPort}${contextPath}"
String httpsBaseUrl = "https://${host}:${httpsPort}${contextPath}"
String baseUrl = isHttps ? httpsBaseUrl : httpBaseUrl
integrationTest.systemProperty 'app.port', port
integrationTest.systemProperty 'app.httpPort', httpPort
integrationTest.systemProperty 'app.httpsPort', httpsPort
integrationTest.systemProperty 'app.baseURI', baseUrl
integrationTest.systemProperty 'app.httpBaseURI', httpBaseUrl
integrationTest.systemProperty 'app.httpsBaseURI', httpsBaseUrl
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https://services.gradle.org/distributions/gradle-7.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading