diff --git a/samples/xml/cas/cassample/spring-security-samples-xml-cassample.gradle b/samples/xml/cas/cassample/spring-security-samples-xml-cassample.gradle
index ba67be2f28..9fedcea3bd 100644
--- a/samples/xml/cas/cassample/spring-security-samples-xml-cassample.gradle
+++ b/samples/xml/cas/cassample/spring-security-samples-xml-cassample.gradle
@@ -3,12 +3,6 @@ apply plugin: 'io.spring.convention.spring-sample-war'
def keystore = "$rootDir/samples/certificates/server.jks"
def password = 'password'
-
-sourceSets {
- test.resources.exclude 'GebConfig.groovy'
- integrationTest.groovy.srcDir file('src/integration-test/groovy')
-}
-
dependencies {
compile project(':spring-security-cas')
compile project(':spring-security-core')
@@ -24,10 +18,7 @@ dependencies {
runtime 'org.springframework:spring-context-support'
integrationTestCompile project(':spring-security-cas')
- integrationTestCompile gebDependencies
integrationTestCompile seleniumDependencies
- integrationTestCompile spockDependencies
- integrationTestCompile 'org.codehaus.groovy:groovy'
integrationTestCompile 'org.eclipse.jetty:jetty-server'
integrationTestCompile 'org.eclipse.jetty:jetty-servlet'
integrationTestCompile 'org.slf4j:jcl-over-slf4j'
@@ -40,8 +31,6 @@ integrationTest {
def casServerHost = 'localhost:' + casServer().gretty.httpsPort
systemProperties['cas.server.host'] = casServerHost
systemProperties['cas.service.host'] = casServiceHost
- systemProperties['geb.build.baseUrl'] = 'https://'+casServiceHost+'/cas-sample/'
- systemProperties['geb.build.reportsDir'] = 'build/geb-reports'
systemProperties['jar.path'] = jar.archivePath
systemProperties['javax.net.ssl.trustStore'] = keystore
systemProperties['javax.net.ssl.trustStorePassword'] = password
diff --git a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/AbstractCasTests.groovy b/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/AbstractCasTests.groovy
deleted file mode 100644
index 87b2e9f88d..0000000000
--- a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/AbstractCasTests.groovy
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2002-2011 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.
- */
-package org.springframework.security.samples.cas
-
-import org.springframework.security.samples.cas.pages.LoginPage;
-
-import java.io.File;
-
-import geb.spock.*
-
-
-/**
- * Base test for Geb testing.
- *
- * @author Rob Winch
- */
-class AbstractCasTests extends GebReportingSpec {
-
- def cleanupSpec() {
- to LoginPage
- resetBrowser()
- }
-}
diff --git a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/CasSampleProxyTests.groovy b/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/CasSampleProxyTests.groovy
deleted file mode 100644
index 269cf5d79a..0000000000
--- a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/CasSampleProxyTests.groovy
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2002-2011 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.
- */
-package org.springframework.security.samples.cas
-
-import org.apache.commons.httpclient.HttpClient
-import org.apache.commons.httpclient.methods.GetMethod
-import org.jasig.cas.client.jaas.CasLoginModule;
-import org.jasig.cas.client.proxy.Cas20ProxyRetriever
-import org.springframework.security.samples.cas.pages.*
-
-import spock.lang.*
-
-
-/**
- * Tests authenticating to the CAS Sample application using Proxy Tickets. Geb is used to authenticate the {@link JettyCasService}
- * to the CAS Server in order to obtain the Ticket Granting Ticket. Afterwards HttpClient is used for accessing the CAS Sample application
- * using Proxy Tickets obtained using the Proxy Granting Ticket.
- *
- * @author Rob Winch
- */
-@Stepwise
-class CasSampleProxyTests extends AbstractCasTests {
- HttpClient client = new HttpClient()
- @Shared String casServerUrl = LoginPage.url.replaceFirst('/login','')
- @Shared JettyCasService service = new JettyCasService().init(casServerUrl)
- @Shared Cas20ProxyRetriever retriever = new Cas20ProxyRetriever(casServerUrl,'UTF-8')
- @Shared String pt
-
- def cleanupSpec() {
- service.stop()
- }
-
- def 'access secure page succeeds with ROLE_USER'() {
- setup: 'Obtain a pgt for a user with ROLE_USER'
- driver.get LoginPage.url+"?service="+service.serviceUrl()
- at LoginPage
- login 'scott'
- when: 'User with ROLE_USER accesses the secure page'
- def content = getSecured(getBaseUrl()+SecurePage.url).responseBodyAsString
- then: 'The secure page is returned'
- content.contains('
Secure Page
')
- }
-
- def 'access proxy ticket sample succeeds with ROLE_USER'() {
- when: 'a proxy ticket is used to create another proxy ticket'
- def content = getSecured(getBaseUrl()+ProxyTicketSamplePage.url).responseBodyAsString
- then: 'The proxy ticket sample page is returned'
- content.contains('Secure Page using a Proxy Ticket
')
- }
-
- def 'access extremely secure page with ROLE_USER is denied'() {
- when: 'User with ROLE_USER accesses the extremely secure page'
- GetMethod method = getSecured(getBaseUrl()+ExtremelySecurePage.url)
- then: 'access is denied'
- assert method.responseBodyAsString =~ /(?i)403.*?Denied/
- assert 403 == method.statusCode
- }
-
- def 'access secure page with ROLE_SUPERVISOR succeeds'() {
- setup: 'Obtain pgt for user with ROLE_SUPERVISOR'
- to LocalLogoutPage
- casServerLogout.click()
- driver.get(LoginPage.url+"?service="+service.serviceUrl())
- at LoginPage
- login 'rod'
- when: 'User with ROLE_SUPERVISOR accesses the secure page'
- def content = getSecured(getBaseUrl()+ExtremelySecurePage.url).responseBodyAsString
- then: 'The secure page is returned'
- content.contains('VERY Secure Page
')
- }
-
- def 'access extremely secure page with ROLE_SUPERVISOR reusing pt succeeds (stateless mode works)'() {
- when: 'User with ROLE_SUPERVISOR accesses extremely secure page with used pt'
- def content = getSecured(getBaseUrl()+ExtremelySecurePage.url,pt).responseBodyAsString
- then: 'The extremely secure page is returned'
- content.contains('VERY Secure Page
')
- }
-
- def 'access secure page with invalid proxy ticket fails'() {
- when: 'Invalid ticket is used to access secure page'
- GetMethod method = getSecured(getBaseUrl()+SecurePage.url,'invalidticket')
- then: 'Authentication fails'
- method.statusCode == 401
- }
-
- /**
- * Gets the result of calling a url with a proxy ticket
- * @param targetUrl the absolute url to attempt to access
- * @param pt the proxy ticket to use. Defaults to {@link #getPt(String)} with targetUrl specified for the targetUrl.
- * @return the GetMethod after calling a url with a specified proxy ticket
- */
- GetMethod getSecured(String targetUrl,String pt=getPt(targetUrl)) {
- assert pt != null
- GetMethod method = new GetMethod(targetUrl+"?ticket="+pt)
- int status = client.executeMethod(method)
- method
- }
-
- /**
- * Obtains a proxy ticket using the pgt from the {@link #service}.
- * @param targetService the targetService that the proxy ticket will be valid for
- * @return a proxy ticket for targetService
- */
- String getPt(String targetService) {
- assert service.pgt != null
- pt = retriever.getProxyTicketIdFor(service.pgt, targetService)
- pt
- }
-}
diff --git a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/CasSampleTests.groovy b/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/CasSampleTests.groovy
deleted file mode 100644
index 341d0ae9a5..0000000000
--- a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/CasSampleTests.groovy
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2002-2011 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.
- */
-package org.springframework.security.samples.cas
-
-import geb.spock.*
-
-import org.apache.http.impl.conn.DefaultClientConnectionOperator;
-import org.junit.runner.RunWith;
-import org.spockframework.runtime.Sputnik;
-import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
-import org.springframework.security.core.context.ThreadLocalSecurityContextHolderStrategy;
-import org.springframework.security.samples.cas.pages.*
-
-import spock.lang.Shared;
-import spock.lang.Stepwise;
-
-/**
- * Tests the CAS sample application using service tickets.
- *
- * @author Rob Winch
- */
-@Stepwise
-class CasSampleTests extends AbstractCasTests {
- @Shared String casServerLogoutUrl = LoginPage.url.replaceFirst('/login','/logout')
-
- def 'access home page with unauthenticated user succeeds'() {
- when: 'Unauthenticated user accesses the Home Page'
- to HomePage
- then: 'The home page succeeds'
- at HomePage
- }
-
- def 'access extremely secure page with unauthenitcated user requires login'() {
- when: 'Unauthenticated user accesses the extremely secure page'
- via ExtremelySecurePage
- then: 'The login page is displayed'
- at LoginPage
- }
-
- def 'authenticate attempt with invaid ticket fails'() {
- when: 'present invalid ticket'
- go "login/cas?ticket=invalid"
- then: 'the login failed page is displayed'
- $("h2").text() == 'Login to CAS failed!'
- }
-
- def 'access secure page with unauthenticated user requires login'() {
- when: 'Unauthenticated user accesses the secure page'
- via SecurePage
- then: 'The login page is displayed'
- at LoginPage
- }
-
- def 'saved request is used for secure page'() {
- when: 'login with ROLE_USER after requesting the secure page'
- login 'scott'
- then: 'the secure page is displayed'
- at SecurePage
- }
-
- def 'access proxy ticket sample with ROLE_USER is allowed'() {
- when: 'user with ROLE_USER requests the proxy ticket sample page'
- to ProxyTicketSamplePage
- then: 'the proxy ticket sample page is displayed'
- at ProxyTicketSamplePage
- }
-
- def 'access extremely secure page with ROLE_USER is denied'() {
- when: 'User with ROLE_USER accesses extremely secure page'
- via ExtremelySecurePage
- then: 'the access denied page is displayed'
- at AccessDeniedPage
- }
-
- def 'clicking local logout link displays local logout page'() {
- setup: 'Navigate to page with logout link'
- to SecurePage
- when: 'Local logout link is clicked'
- navModule.logout.click()
- then: 'the local logout page is displayed'
- at LocalLogoutPage
- }
-
- def 'clicking cas server logout link successfully performs logout'() {
- when: 'the cas server logout link is clicked and the secure page is requested'
- casServerLogout.click()
- via SecurePage
- then: 'the login page is displayed'
- at LoginPage
- }
-
- def 'access extremely secure page with ROLE_SUPERVISOR succeeds'() {
- setup: 'login with ROLE_SUPERVISOR'
- login 'rod'
- when: 'access extremely secure page'
- to ExtremelySecurePage
- then: 'extremely secure page is displayed'
- at ExtremelySecurePage
- }
-
- def 'after logout extremely secure page requires login'() {
- when: 'logout and request extremely secure page'
- navModule.logout.click()
- casServerLogout.click()
- via ExtremelySecurePage
- then: 'login page is displayed'
- at LoginPage
- }
-
- def 'logging out of the cas server successfully logs out of the cas sample application'() {
- setup: 'login with ROLE_USER'
- via SecurePage
- at LoginPage
- login 'rod'
- at SecurePage
- when: 'logout of the CAS Server'
- go casServerLogoutUrl
- via SecurePage
- then: 'user is logged out of the CAS Service'
- at LoginPage
- }
-}
diff --git a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/modules/NavModule.groovy b/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/modules/NavModule.groovy
deleted file mode 100644
index be59e8c31f..0000000000
--- a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/modules/NavModule.groovy
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2002-2011 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.
- */
-package org.springframework.security.samples.cas.modules;
-
-import geb.*
-import org.springframework.security.samples.cas.pages.*
-
-/**
- * Represents the navigation for the CAS Sample application
- *
- * @author Rob Winch
- */
-class NavModule extends Module {
- static content = {
- home(to: HomePage) { $("a", text: "Home") }
- logout(to: LocalLogoutPage) { $("a", text: "Logout") }
- }
-}
diff --git a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/ExtremelySecurePage.groovy b/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/ExtremelySecurePage.groovy
deleted file mode 100644
index 580656764a..0000000000
--- a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/ExtremelySecurePage.groovy
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2002-2011 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.
- */
-package org.springframework.security.samples.cas.pages;
-
-import geb.*
-import org.springframework.security.samples.cas.modules.*
-
-/**
- * Represents the extremely secure page of the CAS Sample application.
- *
- * @author Rob Winch
- */
-class ExtremelySecurePage extends Page {
- static url = "secure/extreme/"
- static at = { assert $('h1').text() == 'VERY Secure Page'; true; }
- static content = {
- navModule { module NavModule }
- }
-}
diff --git a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/HomePage.groovy b/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/HomePage.groovy
deleted file mode 100644
index fa14033ec8..0000000000
--- a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/HomePage.groovy
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2002-2011 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.
- */
-package org.springframework.security.samples.cas.pages
-
-import geb.*
-
-/**
- * Represents the Home page of the CAS sample application
- *
- * @author Rob Winch
- */
-class HomePage extends Page {
- static at = { assert $('h1').text() == 'Home Page'; true}
- static url = ''
- static content = {
- securePage { $('a',text: 'Secure page') }
- extremelySecurePage { $('a',text: 'Extremely secure page') }
- }
-}
diff --git a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/LoginPage.groovy b/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/LoginPage.groovy
deleted file mode 100644
index 2d06717b85..0000000000
--- a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/LoginPage.groovy
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2002-2011 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.
- */
-package org.springframework.security.samples.cas.pages;
-
-import geb.*
-
-/**
- * The CAS login page.
- *
- * @author Rob Winch
- */
-class LoginPage extends Page {
- static url = loginUrl()
- static at = { assert driver.currentUrl.startsWith(loginUrl()); true}
- static content = {
- login(required:false) { user, password=user ->
- loginForm.username = user
- loginForm.password = password
- submit.click()
- }
- loginForm { $('#login') }
- submit { $('input', type: 'submit') }
- }
-
- /**
- * Gets the login page url which might change based upon the system properties. This is to support using a randomly available port for CI.
- * @return
- */
- private static String loginUrl() {
- def host = System.getProperty('cas.server.host', 'localhost:9443')
- "https://${host}/cas/login"
- }
-}
diff --git a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/ProxyTicketSamplePage.groovy b/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/ProxyTicketSamplePage.groovy
deleted file mode 100644
index 4a4fb22619..0000000000
--- a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/ProxyTicketSamplePage.groovy
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2002-2011 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.
- */
-package org.springframework.security.samples.cas.pages;
-
-import geb.*
-import org.springframework.security.samples.cas.modules.*
-
-
-/**
- * Represents the proxy ticket sample page within the CAS Sample application.
- *
- * @author Rob Winch
- */
-class ProxyTicketSamplePage extends Page {
- static url = "secure/ptSample"
- static at = { assert $('h1').text() == 'Secure Page using a Proxy Ticket'; true}
- static content = {
- navModule { module NavModule }
- }
-}
diff --git a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/SecurePage.groovy b/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/SecurePage.groovy
deleted file mode 100644
index 0d069c3df3..0000000000
--- a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/SecurePage.groovy
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2002-2011 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.
- */
-package org.springframework.security.samples.cas.pages;
-
-import geb.*
-import org.springframework.security.samples.cas.modules.*
-
-
-/**
- * Represents the secure page within the CAS Sample application.
- *
- * @author Rob Winch
- */
-class SecurePage extends Page {
- static url = "secure/"
- static at = { assert $('h1').text() == 'Secure Page'; true}
- static content = {
- navModule { module NavModule }
- }
-}
diff --git a/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/CasSampleProxyTests.java b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/CasSampleProxyTests.java
new file mode 100644
index 0000000000..de65160781
--- /dev/null
+++ b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/CasSampleProxyTests.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2002-2011 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.
+ */
+package org.springframework.security.samples.cas;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jasig.cas.client.proxy.Cas20ProxyRetriever;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.htmlunit.HtmlUnitDriver;
+
+import org.springframework.security.samples.cas.pages.AccessDeniedPage;
+import org.springframework.security.samples.cas.pages.ExtremelySecurePage;
+import org.springframework.security.samples.cas.pages.LoginPage;
+import org.springframework.security.samples.cas.pages.ProxyTicketSamplePage;
+import org.springframework.security.samples.cas.pages.SecurePage;
+import org.springframework.security.samples.cas.pages.UnauthorizedPage;
+
+/**
+ * Tests authenticating to the CAS Sample application using Proxy Tickets. Geb is used to authenticate the {@link JettyCasService}
+ * to the CAS Server in order to obtain the Ticket Granting Ticket. Afterwards HttpClient is used for accessing the CAS Sample application
+ * using Proxy Tickets obtained using the Proxy Granting Ticket.
+ *
+ * @author Rob Winch
+ * @author Josh Cummings
+ */
+public class CasSampleProxyTests {
+ private static String serverUrl;
+ private static String serviceUrl;
+ private static JettyCasService service;
+ private static Cas20ProxyRetriever retriever;
+
+ private WebDriver driver = new HtmlUnitDriver();
+
+ private LoginPage login;
+ private SecurePage secure;
+ private ExtremelySecurePage extremelySecure;
+ private ProxyTicketSamplePage proxyTicketSample;
+ private AccessDeniedPage accessDenied;
+ private UnauthorizedPage unauthorized;
+
+ @BeforeClass
+ public static void setupClass() {
+ String serverHost = System.getProperty("cas.server.host", "localhost:8443");
+ serverUrl = "https://" + serverHost + "/cas";
+ String serviceHost = System.getProperty("cas.service.host", "localhost:8443");
+ serviceUrl = "https://" + serviceHost + "/cas-sample";
+ service = new JettyCasService().init(serverUrl);
+ retriever = new Cas20ProxyRetriever(serverUrl, "UTF-8");
+ }
+
+ @AfterClass
+ public static void teardownClass() throws Exception {
+ service.stop();
+ }
+
+ @Before
+ public void setup() {
+ this.login = new LoginPage(this.driver, serverUrl);
+ this.secure = new SecurePage(this.driver, serviceUrl);
+ this.extremelySecure = new ExtremelySecurePage(this.driver, serviceUrl);
+ this.proxyTicketSample = new ProxyTicketSamplePage(this.driver, serviceUrl);
+ this.accessDenied = new AccessDeniedPage(this.driver);
+ this.unauthorized = new UnauthorizedPage(this.driver);
+ }
+
+ @After
+ public void teardown() {
+ this.driver.close();
+ }
+
+ @Test
+ public void securePageWhenRoleUserThenDisplays() {
+ this.login.to(this::serviceParam).assertAt().login("scott");
+ this.secure.to(this::ticketParam).assertAt();
+ }
+
+ @Test
+ public void proxyTicketSamplePageWhenRoleUserThenDisplays() {
+ this.login.to(this::serviceParam).assertAt().login("scott");
+ this.proxyTicketSample.to(this::ticketParam).assertAt();
+ }
+
+ @Test
+ public void extremelySecurePageWhenRoleUserThenDenies() {
+ this.login.to(this::serviceParam).assertAt().login("scott");
+ this.extremelySecure.to(this::ticketParam);
+ this.accessDenied.assertAt();
+ }
+
+ @Test
+ public void extremelySecurePageWhenRoleSupervisorThenDisplays() {
+ this.login.to(this::serviceParam).assertAt().login("rod");
+ this.extremelySecure.to(this::ticketParam).assertAt();
+ }
+
+ @Test
+ public void extremelySecurePageWhenReusingTicketThenDisplays() {
+ this.login.to(this::serviceParam).assertAt().login("rod");
+ Map ptCache = new HashMap<>();
+ this.extremelySecure.to(url -> url + "?ticket=" + ptCache.computeIfAbsent(url, this::getPt)).assertAt();
+ this.extremelySecure.to(url -> url + "?ticket=" + ptCache.get(url)).assertAt();
+ }
+
+ @Test
+ public void securePageWhenInvalidTicketThenFails() {
+ this.login.to(this::serviceParam).assertAt().login("scott");
+ this.secure.to(url -> url + "?ticket=invalid");
+ this.unauthorized.assertAt();
+ }
+
+ private String serviceParam(String url) {
+ return url + "?service=" + service.serviceUrl();
+ }
+
+ private String ticketParam(String url) {
+ return url + "?ticket=" + getPt(url);
+ }
+
+ /**
+ * Obtains a proxy ticket using the pgt from the {@link #service}.
+ * @param targetService the targetService that the proxy ticket will be valid for
+ * @return a proxy ticket for targetService
+ */
+ String getPt(String targetService) {
+ assert service.pgt != null;
+ return retriever.getProxyTicketIdFor(service.pgt, targetService);
+ }
+}
diff --git a/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/CasSampleTests.java b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/CasSampleTests.java
new file mode 100644
index 0000000000..c03ef891fc
--- /dev/null
+++ b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/CasSampleTests.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2002-2011 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.
+ */
+package org.springframework.security.samples.cas;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.htmlunit.HtmlUnitDriver;
+
+import org.springframework.security.samples.cas.pages.AccessDeniedPage;
+import org.springframework.security.samples.cas.pages.ExtremelySecurePage;
+import org.springframework.security.samples.cas.pages.HomePage;
+import org.springframework.security.samples.cas.pages.LocalLogoutPage;
+import org.springframework.security.samples.cas.pages.LoginPage;
+import org.springframework.security.samples.cas.pages.ProxyTicketSamplePage;
+import org.springframework.security.samples.cas.pages.SecurePage;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests the CAS sample application using service tickets.
+ *
+ * @author Rob Winch
+ * @author Josh Cummings
+ */
+public class CasSampleTests {
+ private WebDriver driver = new HtmlUnitDriver();
+
+ private String serviceUrl;
+ private String serverUrl;
+
+ private LoginPage login;
+
+ private HomePage home;
+ private SecurePage secure;
+ private ExtremelySecurePage extremelySecure;
+ private ProxyTicketSamplePage proxyTicketSample;
+ private LocalLogoutPage localLogout;
+ private AccessDeniedPage accessDenied;
+
+ @Before
+ public void setup() {
+ String serverHost = System.getProperty("cas.server.host", "localhost:8443");
+ this.serverUrl = "https://" + serverHost + "/cas";
+ String serviceHost = System.getProperty("cas.service.host", "localhost:8443");
+ this.serviceUrl = "https://" + serviceHost + "/cas-sample";
+ this.login = new LoginPage(this.driver, this.serverUrl);
+ this.home = new HomePage(this.driver, this.serviceUrl);
+ this.secure = new SecurePage(this.driver, this.serviceUrl);
+ this.extremelySecure = new ExtremelySecurePage(this.driver, this.serviceUrl);
+ this.proxyTicketSample = new ProxyTicketSamplePage(this.driver, this.serviceUrl);
+ this.localLogout = new LocalLogoutPage(this.driver, this.serviceUrl);
+ this.accessDenied = new AccessDeniedPage(this.driver);
+ }
+
+ @After
+ public void tearDown() {
+ this.driver.close();
+ }
+
+ @Test
+ public void homePageWhenUnauthenticatedUserThenSucceeds() {
+ this.home.to().assertAt();
+ }
+
+ @Test
+ public void extremelySecurePageWhenUnauthenticatedThenRequiresLogin() {
+ this.extremelySecure.to();
+ this.login.assertAt();
+ }
+
+ @Test
+ public void authenticateWhenInvalidTicketThenFails() {
+ this.driver.get(this.serviceUrl + "/login/cas?ticket=invalid");
+ assertThat(this.driver.findElement(By.tagName("h2")).getText())
+ .isEqualTo("Login to CAS failed!");
+ }
+
+ @Test
+ public void securePageWhenUnauthenticatedThenRequiresLogin() {
+ this.secure.to();
+ this.login.assertAt();
+ }
+
+ @Test
+ public void securePageWhenRoleUserThenDisplays() {
+ this.login.to().login("scott");
+ this.secure.to().assertAt();
+ }
+
+ @Test
+ public void proxyTicketSamplePageWhenRoleUserThenDisplays() {
+ this.login.to().login("scott");
+ this.proxyTicketSample.to().assertAt();
+ }
+
+ @Test
+ public void extremelySecurePageWhenRoleUserThenDenies() {
+ this.login.to().login("scott");
+ this.extremelySecure.to();
+ this.accessDenied.assertAt();
+ }
+
+ @Test
+ public void localLogoutLinkWhenClickedThenRedirectsToLocalLogoutPage() {
+ this.login.to().login("scott");
+ this.secure.to().logout();
+ this.localLogout.assertAt();
+ }
+
+ @Test
+ public void casLogoutWhenClickedThenPerformsCompleteLogout() {
+ this.login.to().login("scott");
+ this.driver.get(this.serverUrl + "/logout");
+ this.secure.to();
+ this.login.assertAt();
+ }
+
+ @Test
+ public void extremelySecureWhenRoleSupervisorThenDisplays() {
+ this.login.to().login("rod");
+ this.extremelySecure.to().assertAt();
+ }
+
+ @Test
+ public void casLogoutWhenClickedThenExtremelySecurePageRequiresLogin() {
+ this.login.to().login("scott");
+ this.driver.get(this.serverUrl + "/logout");
+ this.extremelySecure.to();
+ this.login.assertAt();
+ }
+
+ @Test
+ public void casLogoutWhenVisitedThenLogsOutSample() {
+ this.secure.to();
+ this.login.assertAt().login("rod");
+ this.secure.assertAt();
+ this.driver.get(this.serverUrl + "/logout");
+ this.secure.to();
+ this.login.assertAt();
+ }
+}
diff --git a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/JettyCasService.groovy b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/JettyCasService.java
similarity index 53%
rename from samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/JettyCasService.groovy
rename to samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/JettyCasService.java
index 8be5860fb2..1491beb6f2 100644
--- a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/JettyCasService.groovy
+++ b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/JettyCasService.java
@@ -13,41 +13,46 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.springframework.security.samples.cas
+package org.springframework.security.samples.cas;
-import org.eclipse.jetty.http.HttpVersion
-import org.eclipse.jetty.server.HttpConfiguration
-import org.eclipse.jetty.server.HttpConnectionFactory
-import org.eclipse.jetty.server.SecureRequestCustomizer
-import org.eclipse.jetty.server.ServerConnector
-import org.eclipse.jetty.server.SslConnectionFactory
+import java.io.File;
+import java.io.IOException;
+import java.net.ServerSocket;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpVersion;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.ssl.SslContextFactory;
-
-import javax.servlet.ServletException
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-
-import org.eclipse.jetty.server.Request
-import org.eclipse.jetty.server.Server
-import org.eclipse.jetty.server.handler.AbstractHandler
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl;
import org.jasig.cas.client.validation.Cas20ProxyTicketValidator;
+import org.jasig.cas.client.validation.TicketValidationException;
+
+import org.springframework.util.StringUtils;
/**
* A CAS Service that allows a PGT to be obtained. This is useful for testing use of proxy tickets.
*
* @author Rob Winch
*/
-class JettyCasService extends Server {
- private Cas20ProxyTicketValidator validator
- private int port = availablePort()
+public class JettyCasService extends Server {
+ private Cas20ProxyTicketValidator validator;
+ private int port = availablePort();
/**
* The Proxy Granting Ticket. To initialize pgt, authenticate to the CAS Server with the service parameter
* equal to {@link #serviceUrl()}.
*/
- String pgt
+ String pgt;
/**
* Start the CAS Service which will be available at {@link #serviceUrl()}.
@@ -55,16 +60,15 @@ class JettyCasService extends Server {
* @param casServerUrl
* @return
*/
- def init(String casServerUrl) {
- println "Initializing to " + casServerUrl
- ProxyGrantingTicketStorage storage = new ProxyGrantingTicketStorageImpl()
- validator = new Cas20ProxyTicketValidator(casServerUrl)
- validator.setAcceptAnyProxy(true)
- validator.setProxyGrantingTicketStorage(storage)
- validator.setProxyCallbackUrl(absoluteUrl('callback'))
-
- String password = System.getProperty('javax.net.ssl.trustStorePassword','password')
+ JettyCasService init(String casServerUrl) {
+ System.out.println("Initializing to " + casServerUrl);
+ ProxyGrantingTicketStorage storage = new ProxyGrantingTicketStorageImpl();
+ this.validator = new Cas20ProxyTicketValidator(casServerUrl);
+ this.validator.setAcceptAnyProxy(true);
+ this.validator.setProxyGrantingTicketStorage(storage);
+ this.validator.setProxyCallbackUrl(absoluteUrl("callback"));
+ String password = System.getProperty("javax.net.ssl.trustStorePassword", "password");
SslContextFactory sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setKeyStorePath(getTrustStore());
@@ -83,30 +87,39 @@ class JettyCasService extends Server {
https_config.addCustomizer(src);
ServerConnector https = new ServerConnector(this,
- new SslConnectionFactory(sslContextFactory,HttpVersion.HTTP_1_1.asString()),
+ new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
new HttpConnectionFactory(https_config));
https.setPort(port);
https.setIdleTimeout(500000);
- addConnector(https)
+ addConnector(https);
setHandler(new AbstractHandler() {
public void handle(String target, Request baseRequest,
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
- def st = request.getParameter('ticket')
- if(st) {
- JettyCasService.this.validator.validate(st, JettyCasService.this.serviceUrl())
+ String st = request.getParameter("ticket");
+ if (StringUtils.hasText(st)) {
+ try {
+ JettyCasService.this.validator.validate(st, JettyCasService.this.serviceUrl());
+ } catch (TicketValidationException e) {
+ throw new IllegalArgumentException(e);
+ }
}
- def pgt = request.getParameter('pgtId')
- if(pgt) {
- JettyCasService.this.pgt = pgt
+ String pgt = request.getParameter("pgtId");
+ if (StringUtils.hasText(pgt)) {
+ JettyCasService.this.pgt = pgt;
}
response.setStatus(HttpServletResponse.SC_OK);
baseRequest.setHandled(true);
}
- })
- start()
- this
+ });
+
+ try {
+ start();
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ return this;
}
/**
@@ -114,7 +127,7 @@ class JettyCasService extends Server {
* @return
*/
String serviceUrl() {
- absoluteUrl('service')
+ return absoluteUrl("service");
}
/**
@@ -123,24 +136,27 @@ class JettyCasService extends Server {
* @return
*/
private String absoluteUrl(String relativeUrl) {
- "https://localhost:${port}/${relativeUrl}"
+ return "https://localhost:" + port + "/" + relativeUrl;
}
private static String getTrustStore() {
- String trustStoreLocation = System.getProperty('javax.net.ssl.trustStore')
- if(trustStoreLocation == null || !new File(trustStoreLocation).isFile()) {
- throw new IllegalStateException('Could not find the trust store at path "'+trustStoreLocation+'". Specify the location using the javax.net.ssl.trustStore system property.')
+ String trustStoreLocation = System.getProperty("javax.net.ssl.trustStore");
+ if (trustStoreLocation == null || !new File(trustStoreLocation).isFile()) {
+ throw new IllegalStateException("Could not find the trust store at path \"" + trustStoreLocation +
+ "\". Specify the location using the javax.net.ssl.trustStore system property.");
}
- trustStoreLocation
+ return trustStoreLocation;
}
+
/**
* Obtains a random available port (i.e. one that is not in use)
* @return
*/
private static int availablePort() {
- ServerSocket server = new ServerSocket(0)
- int port = server.localPort
- server.close()
- port
+ try (ServerSocket server = new ServerSocket(0)) {
+ return server.getLocalPort();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
}
}
diff --git a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/AccessDeniedPage.groovy b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/AccessDeniedPage.java
similarity index 51%
rename from samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/AccessDeniedPage.groovy
rename to samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/AccessDeniedPage.java
index 686762673d..e1426a360f 100644
--- a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/AccessDeniedPage.groovy
+++ b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/AccessDeniedPage.java
@@ -15,13 +15,38 @@
*/
package org.springframework.security.samples.cas.pages;
-import geb.*
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+
+import static org.assertj.core.api.Assertions.assertThat;
/**
* Represents the access denied page
*
* @author Rob Winch
+ * @author Josh Cummings
*/
-class AccessDeniedPage extends Page {
- static at = { $("*",text: iContains(~/.*?403.*/)) }
+public class AccessDeniedPage {
+
+ private final Content content;
+
+ public AccessDeniedPage(WebDriver driver) {
+ this.content = PageFactory.initElements(driver, Content.class);
+ }
+
+ public AccessDeniedPage assertAt() {
+ assertThat(this.content.header()).contains("403 - Access Denied");
+ return this;
+ }
+
+ public static class Content {
+ @FindBy(tagName="h1")
+ WebElement header;
+
+ public String header() {
+ return this.header.getText();
+ }
+ }
}
diff --git a/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/ExtremelySecurePage.java b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/ExtremelySecurePage.java
new file mode 100644
index 0000000000..7ad5e5d0ee
--- /dev/null
+++ b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/ExtremelySecurePage.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2002-2011 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.
+ */
+package org.springframework.security.samples.cas.pages;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Represents the extremely secure page of the CAS Sample application.
+ *
+ * @author Rob Winch
+ * @author Josh Cummings
+ */
+public class ExtremelySecurePage extends Page {
+ private final Content content;
+
+ public ExtremelySecurePage(WebDriver driver, String baseUrl) {
+ super(driver, baseUrl + "/secure/extreme");
+ this.content = PageFactory.initElements(driver, Content.class);
+ }
+
+ @Override
+ public ExtremelySecurePage assertAt() {
+ assertThat(this.content.getText()).isEqualTo("VERY Secure Page");
+ return this;
+ }
+
+ public static class Content {
+ @FindBy(tagName="h1")
+ WebElement header;
+
+ public String getText() {
+ return this.header.getText();
+ }
+ }
+}
diff --git a/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/HomePage.java b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/HomePage.java
new file mode 100644
index 0000000000..25cf8dbded
--- /dev/null
+++ b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/HomePage.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2002-2011 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.
+ */
+package org.springframework.security.samples.cas.pages;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Represents the Home page of the CAS sample application
+ *
+ * @author Rob Winch
+ * @author Josh Cummings
+ */
+public class HomePage extends Page {
+ private final Content content;
+
+ public HomePage(WebDriver driver, String baseUrl) {
+ super(driver, baseUrl);
+ this.content = PageFactory.initElements(driver, Content.class);
+ }
+
+ @Override
+ public HomePage assertAt() {
+ assertThat(this.content.header()).isEqualTo("Home Page");
+ return this;
+ }
+
+ public static class Content {
+ @FindBy(tagName="h1")
+ WebElement header;
+
+ public String header() {
+ return this.header.getText();
+ }
+ }
+}
diff --git a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/LocalLogoutPage.groovy b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/LocalLogoutPage.java
similarity index 83%
rename from samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/LocalLogoutPage.groovy
rename to samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/LocalLogoutPage.java
index 1376d6aeed..075a792080 100644
--- a/samples/xml/cas/cassample/src/integration-test/groovy/org/springframework/security/samples/cas/pages/LocalLogoutPage.groovy
+++ b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/LocalLogoutPage.java
@@ -15,8 +15,7 @@
*/
package org.springframework.security.samples.cas.pages;
-import geb.*
-
+import org.openqa.selenium.WebDriver;
/**
* This represents the local logout page. This page is where the user is logged out of the CAS Sample application, but
@@ -25,11 +24,10 @@ import geb.*
* single logout on the other services.
*
* @author Rob Winch
+ * @author Josh Cummings
*/
-class LocalLogoutPage extends Page {
- static url = 'cas-logout.jsp'
- static at = { assert driver.currentUrl.endsWith(url); true }
- static content = {
- casServerLogout { $('a',text: 'Logout of CAS') }
+public class LocalLogoutPage extends Page {
+ public LocalLogoutPage(WebDriver driver, String baseUrl) {
+ super(driver, baseUrl + "/cas-logout.jsp");
}
}
diff --git a/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/LoginPage.java b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/LoginPage.java
new file mode 100644
index 0000000000..44c509905c
--- /dev/null
+++ b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/LoginPage.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2002-2011 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.
+ */
+package org.springframework.security.samples.cas.pages;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+
+/**
+ * The CAS login page.
+ *
+ * @author Rob Winch
+ * @author Josh Cummings
+ */
+public class LoginPage extends Page {
+ private final Content content;
+
+ public LoginPage(WebDriver driver, String baseUrl) {
+ super(driver, baseUrl + "/login");
+ this.content = PageFactory.initElements(driver, Content.class);
+ }
+
+ public void login(String user) {
+ login(user, user);
+ }
+
+ public void login(String user, String password) {
+ this.content.username(user).password(password).submit();
+ }
+
+ public static class Content {
+ private WebElement username;
+ private WebElement password;
+ @FindBy(css = "input[type=submit]")
+ private WebElement submit;
+
+ public Content username(String username) {
+ this.username.sendKeys(username);
+ return this;
+ }
+
+ public Content password(String password) {
+ this.password.sendKeys(password);
+ return this;
+ }
+
+ public void submit() {
+ this.submit.click();
+ }
+ }
+}
diff --git a/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/Page.java b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/Page.java
new file mode 100644
index 0000000000..1e7d4e40c3
--- /dev/null
+++ b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/Page.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2002-2020 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.
+ */
+
+package org.springframework.security.samples.cas.pages;
+
+import java.util.function.Function;
+
+import org.openqa.selenium.WebDriver;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author Josh Cummings
+ */
+public abstract class Page> {
+ private final WebDriver driver;
+ private final String url;
+
+ protected Page(WebDriver driver, String url) {
+ this.driver = driver;
+ this.url = url;
+ }
+
+ public T assertAt() {
+ assertThat(this.driver.getCurrentUrl()).startsWith(this.url);
+ return (T) this;
+ }
+
+ public T to() {
+ this.driver.get(this.url);
+ return (T) this;
+ }
+
+ public T to(Function urlPostProcessor) {
+ this.driver.get(urlPostProcessor.apply(this.url));
+ return (T) this;
+ }
+}
diff --git a/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/ProxyTicketSamplePage.java b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/ProxyTicketSamplePage.java
new file mode 100644
index 0000000000..4f4bd78fa3
--- /dev/null
+++ b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/ProxyTicketSamplePage.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2002-2011 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.
+ */
+package org.springframework.security.samples.cas.pages;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Represents the proxy ticket sample page within the CAS Sample application.
+ *
+ * @author Rob Winch
+ * @author Josh Cummings
+ */
+public class ProxyTicketSamplePage extends Page {
+ private final Content content;
+
+ public ProxyTicketSamplePage(WebDriver driver, String baseUrl) {
+ super(driver, baseUrl + "/secure/ptSample");
+ this.content = PageFactory.initElements(driver, Content.class);
+ }
+
+ @Override
+ public ProxyTicketSamplePage assertAt() {
+ assertThat(this.content.getText()).isEqualTo("Secure Page using a Proxy Ticket");
+ return this;
+ }
+
+ public static class Content {
+ @FindBy(tagName="h1")
+ WebElement header;
+
+ public String getText() {
+ return this.header.getText();
+ }
+ }
+}
diff --git a/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/SecurePage.java b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/SecurePage.java
new file mode 100644
index 0000000000..7b5afe0093
--- /dev/null
+++ b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/SecurePage.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2002-2011 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.
+ */
+package org.springframework.security.samples.cas.pages;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Represents the secure page within the CAS Sample application.
+ *
+ * @author Rob Winch
+ * @author Josh Cummings
+ */
+public class SecurePage extends Page {
+ private final Content content;
+
+ public SecurePage(WebDriver driver, String baseUrl) {
+ super(driver, baseUrl + "/secure");
+ this.content = PageFactory.initElements(driver, Content.class);
+ }
+
+ @Override
+ public SecurePage assertAt() {
+ assertThat(this.content.header()).isEqualTo("Secure Page");
+ return this;
+ }
+
+ public SecurePage logout() {
+ this.content.logout();
+ return this;
+ }
+
+ public static class Content {
+ @FindBy(tagName="h1")
+ WebElement header;
+
+ WebElement logout;
+
+ public String header() {
+ return this.header.getText();
+ }
+
+ public void logout() {
+ this.logout.click();
+ }
+ }
+
+ // had nav
+}
diff --git a/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/UnauthorizedPage.java b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/UnauthorizedPage.java
new file mode 100644
index 0000000000..4b8e099ab1
--- /dev/null
+++ b/samples/xml/cas/cassample/src/integration-test/java/org/springframework/security/samples/cas/pages/UnauthorizedPage.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2002-2011 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.
+ */
+package org.springframework.security.samples.cas.pages;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Represents the unauthorized page
+ *
+ * @author Josh Cummings
+ */
+public class UnauthorizedPage {
+
+ private final Content content;
+
+ public UnauthorizedPage(WebDriver driver) {
+ this.content = PageFactory.initElements(driver, Content.class);
+ }
+
+ public UnauthorizedPage assertAt() {
+ assertThat(this.content.header()).contains("401 - Unauthorized");
+ return this;
+ }
+
+ public static class Content {
+ @FindBy(tagName="h1")
+ WebElement header;
+
+ public String header() {
+ return this.header.getText();
+ }
+ }
+}
diff --git a/samples/xml/cas/cassample/src/main/webapp/401.jsp b/samples/xml/cas/cassample/src/main/webapp/401.jsp
new file mode 100644
index 0000000000..db1a4a1f3e
--- /dev/null
+++ b/samples/xml/cas/cassample/src/main/webapp/401.jsp
@@ -0,0 +1,8 @@
+
+
+401 - Unauthorized
+
+
+401 - Unauthorized
+
+
diff --git a/samples/xml/cas/cassample/src/main/webapp/WEB-INF/web.xml b/samples/xml/cas/cassample/src/main/webapp/WEB-INF/web.xml
index fa78554d48..0cf03709fc 100644
--- a/samples/xml/cas/cassample/src/main/webapp/WEB-INF/web.xml
+++ b/samples/xml/cas/cassample/src/main/webapp/WEB-INF/web.xml
@@ -78,6 +78,10 @@
ptSampleServlet
/secure/ptSample
+
+ 401
+ /401.jsp
+
403
/403.jsp
diff --git a/samples/xml/cas/cassample/src/main/webapp/cas-logout.jsp b/samples/xml/cas/cassample/src/main/webapp/cas-logout.jsp
index 730e3b366c..5658e5d38b 100644
--- a/samples/xml/cas/cassample/src/main/webapp/cas-logout.jsp
+++ b/samples/xml/cas/cassample/src/main/webapp/cas-logout.jsp
@@ -9,7 +9,7 @@
You have logged out of this application, but may still have an active single-sign on session with CAS.
-Logout of CAS
+Logout of CAS