Proxy Ticket Authentication
diff --git a/samples/cas/cas.gradle b/samples/cas/cas.gradle
index 230f2221b5..1715a7bb06 100644
--- a/samples/cas/cas.gradle
+++ b/samples/cas/cas.gradle
@@ -33,8 +33,13 @@ dependencies {
casServer "org.jasig.cas:cas-server-webapp:3.4.3.1@war"
- runtime project(':spring-security-web'),
+ providedCompile 'javax.servlet:servlet-api:2.5@jar'
+
+ compile project(':spring-security-core'),
project(':spring-security-cas'),
+ "org.jasig.cas.client:cas-client-core:3.1.12"
+
+ runtime project(':spring-security-web'),
project(':spring-security-config'),
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
"ch.qos.logback:logback-classic:$logbackVersion"
diff --git a/samples/cas/src/integration-test/groovy/org/springframework/security/samples/cas/CasSampleProxySpec.groovy b/samples/cas/src/integration-test/groovy/org/springframework/security/samples/cas/CasSampleProxySpec.groovy
index ec92ec3ac4..a7ffe6c1a3 100644
--- a/samples/cas/src/integration-test/groovy/org/springframework/security/samples/cas/CasSampleProxySpec.groovy
+++ b/samples/cas/src/integration-test/groovy/org/springframework/security/samples/cas/CasSampleProxySpec.groovy
@@ -54,6 +54,13 @@ class CasSampleProxySpec extends BaseSpec {
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)
diff --git a/samples/cas/src/integration-test/groovy/org/springframework/security/samples/cas/CasSampleSpec.groovy b/samples/cas/src/integration-test/groovy/org/springframework/security/samples/cas/CasSampleSpec.groovy
index 78ddc7621f..e71df91190 100644
--- a/samples/cas/src/integration-test/groovy/org/springframework/security/samples/cas/CasSampleSpec.groovy
+++ b/samples/cas/src/integration-test/groovy/org/springframework/security/samples/cas/CasSampleSpec.groovy
@@ -69,6 +69,13 @@ class CasSampleSpec extends BaseSpec {
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'
to ExtremelySecurePage
diff --git a/samples/cas/src/integration-test/groovy/org/springframework/security/samples/cas/pages/ProxyTicketSamplePage.groovy b/samples/cas/src/integration-test/groovy/org/springframework/security/samples/cas/pages/ProxyTicketSamplePage.groovy
new file mode 100644
index 0000000000..f9cd98657c
--- /dev/null
+++ b/samples/cas/src/integration-test/groovy/org/springframework/security/samples/cas/pages/ProxyTicketSamplePage.groovy
@@ -0,0 +1,33 @@
+/*
+ * Copyright 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
+ *
+ * http://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 }
+ }
+}
\ No newline at end of file
diff --git a/samples/cas/src/main/java/org/springframework/security/samples/cas/web/ProxyTicketSampleServlet.java b/samples/cas/src/main/java/org/springframework/security/samples/cas/web/ProxyTicketSampleServlet.java
new file mode 100644
index 0000000000..e3e0c3bc0c
--- /dev/null
+++ b/samples/cas/src/main/java/org/springframework/security/samples/cas/web/ProxyTicketSampleServlet.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 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
+ *
+ * http://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.web;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URLEncoder;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jasig.cas.client.util.CommonUtils;
+import org.springframework.security.cas.authentication.CasAuthenticationToken;
+
+/**
+ *
+ * {@link ProxyTicketSampleServlet} demonstrates how to obtain a proxy ticket
+ * and then use it to make a remote call. To learn how proxy tickets work, see
+ * the Proxy
+ * CAS Walkthrough
+ *
+ *
+ * @author Rob Winch
+ */
+public final class ProxyTicketSampleServlet extends HttpServlet {
+ /**
+ * This is the URL that will be called and authenticate a proxy ticket.
+ */
+ private String targetUrl;
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+ // NOTE: The CasAuthenticationToken can also be obtained using SecurityContextHolder.getContext().getAuthentication()
+ final CasAuthenticationToken token = (CasAuthenticationToken) request.getUserPrincipal();
+ // proxyTicket could be reused to make calls to to the CAS service even if the target url differs
+ final String proxyTicket = token.getAssertion().getPrincipal().getProxyTicketFor(targetUrl);
+
+ // Make a remote call to ourself. This is a bit silly, but it works well to demonstrate how to use proxy tickets.
+ final String serviceUrl = targetUrl+"?ticket="+URLEncoder.encode(proxyTicket, "UTF-8");
+ String proxyResponse = CommonUtils.getResponseFromServer(serviceUrl, "UTF-8");
+
+ // modify the response and write it out to inform the user that it was obtained using a proxy ticket.
+ proxyResponse = proxyResponse.replaceFirst("Secure Page", "Secure Page using a Proxy Ticket");
+ proxyResponse = proxyResponse.replaceFirst("",
+ "
This page is rendered by "+getClass().getSimpleName()+" by making a remote call to the Secure Page using a proxy ticket ("+proxyTicket+") and inserts this message. ");
+ final PrintWriter writer = response.getWriter();
+ writer.write(proxyResponse);
+ }
+
+ /**
+ * Initialize the target URL. It allows for the host to change based upon
+ * the "cas.service.host" system property. If the property is not set, the
+ * default is "localhost:8443".
+ */
+ @Override
+ public void init() throws ServletException {
+ super.init();
+ String casServiceHost = System.getProperty("cas.service.host", "localhost:8443");
+ targetUrl = "https://"+casServiceHost+"/cas-sample/secure/";
+ }
+
+ private static final long serialVersionUID = -7720161771819727775L;
+}
diff --git a/samples/cas/src/main/webapp/WEB-INF/applicationContext-security.xml b/samples/cas/src/main/webapp/WEB-INF/applicationContext-security.xml
index 78d58960cf..3fc6a6495d 100644
--- a/samples/cas/src/main/webapp/WEB-INF/applicationContext-security.xml
+++ b/samples/cas/src/main/webapp/WEB-INF/applicationContext-security.xml
@@ -57,7 +57,9 @@
+ p:serviceProperties-ref="serviceProperties"
+ p:proxyGrantingTicketStorage-ref="pgtStorage"
+ p:proxyReceptorUrl="/j_spring_cas_security_proxyreceptor">
@@ -66,6 +68,11 @@
p:defaultFailureUrl="/casfailed.jsp"/>
+
+
@@ -78,7 +85,9 @@
+ p:acceptAnyProxy="true"
+ p:proxyCallbackUrl="https://${cas.service.host}/cas-sample/j_spring_cas_security_proxyreceptor"
+ p:proxyGrantingTicketStorage-ref="pgtStorage">
diff --git a/samples/cas/src/main/webapp/WEB-INF/web.xml b/samples/cas/src/main/webapp/WEB-INF/web.xml
index 3675fa76df..0c45c39474 100644
--- a/samples/cas/src/main/webapp/WEB-INF/web.xml
+++ b/samples/cas/src/main/webapp/WEB-INF/web.xml
@@ -69,6 +69,15 @@
org.springframework.web.context.ContextLoaderListener
+
+ ptSampleServlet
+ org.springframework.security.samples.cas.web.ProxyTicketSampleServlet
+
+
+
+ ptSampleServlet
+ /secure/ptSample
+
403
/403.jsp
diff --git a/samples/cas/src/main/webapp/index.jsp b/samples/cas/src/main/webapp/index.jsp
index c815d484a3..546d5996d7 100644
--- a/samples/cas/src/main/webapp/index.jsp
+++ b/samples/cas/src/main/webapp/index.jsp
@@ -6,6 +6,7 @@
Your principal object is....: <%= request.getUserPrincipal() %>
Secure page
+Proxy Ticket Sample page
Extremely secure page