Browse Source

SEC-652: CAS sample application and server using maven jetty plugin.

Luke Taylor 17 years ago
parent
commit
46a69b6d93

+ 53 - 0
samples/cas/Readme.txt

@@ -0,0 +1,53 @@
+There are two subdirectories in this project;
+
+server - this is not a real maven sub-project in the sense that it builds anything. It is just here to allow you to
+         conveniently run the CAS server using the maven Jetty plugin with our preconfigured SSL certificates.
+
+client - this contains the actual sample web application which uses the cas server for authentication. It uses the same
+         certificates. In practice, the CAS server would likely be running on a different machine and both client and
+         server would have different certificates issued to the server hostname.
+
+Running the CAS Server
+-----------------------
+
+You first need to download the CAS server 3.1.1 distribution from
+
+http://www.ja-sig.org/products/cas/downloads/index.html
+
+You only need the modules/cas-server-webapp-3.1.1.war web application file from the distribution. Copy this to the
+"server" directory inside the one that contains this readme file (i.e. copy it to samples/cas/server).
+
+You can then run the CAS server (from the same) by executing the maven command
+
+mvn jetty:run-war
+
+This will start the server on
+
+https://localhost:9443/cas
+
+If you point your browser at this URL, you should see the CAS login screen.
+
+
+Running the Client Application
+-------------------------------
+
+Leave the server running and start up a separate command window to run the sample application. Change to the directory
+samples/cas/client and execute the command
+
+mvn:jetty-run
+
+
+This should start the sample application on
+
+http://localhost:8080/cas-sample/
+
+Try to access the secure page (as with the other samples) and you should be redirected to the CAS server to log in. Note
+that the sample authentication module that comes with the CAS server webapp will authenticate any user whose password
+matches the username. So you have to log in here as rod/rod, dianne/dianne etc. Obviously the usernames must still match
+those listed in the application's user-service. 
+
+
+$Id$
+
+
+

+ 104 - 0
samples/cas/client/pom.xml

@@ -0,0 +1,104 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-samples</artifactId>
+        <version>2.0-SNAPSHOT</version>
+    </parent>
+    <groupId>org.springframework.security</groupId>
+    <artifactId>spring-security-samples-cas-client</artifactId>
+    <name>Spring Security - CAS Sample Client Web Application</name>
+    <packaging>war</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+	        <version>${spring.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-jdbc</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-aop</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>cas</groupId>
+            <artifactId>casclient</artifactId>
+            <version>2.1.1</version>
+        </dependency>
+        <dependency>
+          <groupId>net.sf.ehcache</groupId>
+          <artifactId>ehcache</artifactId>
+          <version>1.2.4</version>
+          <scope>runtime</scope>
+        </dependency>        
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>jstl</artifactId>
+            <version>1.2</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>taglibs</groupId>
+            <artifactId>standard</artifactId>
+            <version>1.0.6</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.4.3</version>
+            <scope>runtime</scope>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.mortbay.jetty</groupId>
+                <artifactId>maven-jetty-plugin</artifactId>
+                <version>6.1.7</version>
+                <configuration>
+                    <contextPath>/cas-sample</contextPath>
+                    <connectors>
+                        <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
+                            <port>8080</port>
+                            <confidentialPort>8443</confidentialPort>
+                        </connector>
+                        <connector implementation="org.mortbay.jetty.security.SslSocketConnector">
+                            <port>8443</port>
+                            <keystore>../../certificates/server.jks</keystore>
+                            <password>password</password>
+                            <keyPassword>password</keyPassword>
+                            <truststore>../../certificates/server.jks</truststore>
+                            <trustPassword>password</trustPassword>
+                        </connector>
+                    </connectors>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 7 - 0
samples/cas/client/src/main/java/Dummy.java

@@ -0,0 +1,7 @@
+/**
+ *
+ * @author Luke Taylor
+ * @version $Id$
+ */
+public class Dummy {
+}

+ 71 - 0
samples/cas/client/src/main/webapp/WEB-INF/applicationContext-security.xml

@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+    xmlns:sec="http://www.springframework.org/schema/security"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
+                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
+    <sec:http>
+        <sec:intercept-url pattern="/secure/extreme/**" access="ROLE_SUPERVISOR" requires-channel="https"/>
+        <sec:intercept-url pattern="/secure/**" access="ROLE_USER" />
+        <sec:logout />
+    </sec:http>
+
+    <bean id="casProcessingFilter" class="org.springframework.security.ui.cas.CasProcessingFilter" autowire="byType">
+        <sec:custom-filter after="CAS_PROCESSING_FILTER"/>
+        <property name="authenticationFailureUrl" value="/casfailed.jsp"/>
+        <property name="defaultTargetUrl" value="/"/>
+    </bean>
+
+    <bean id="casProcessingFilterEntryPoint" class="org.springframework.security.ui.cas.CasProcessingFilterEntryPoint">
+        <property name="loginUrl" value="https://localhost:9443/cas/login"/>
+        <property name="serviceProperties" ref="serviceProperties"/>
+    </bean>
+
+    <bean id="casAuthenticationProvider" class="org.springframework.security.providers.cas.CasAuthenticationProvider">
+        <sec:custom-authentication-provider />
+        <property name="casAuthoritiesPopulator">
+            <bean class="org.springframework.security.providers.DaoAuthoritiesPopulator">
+                <property name="userDetailsService" ref="userService"/>
+            </bean>
+        </property>
+        <property name="casProxyDecider">
+            <bean class="org.springframework.security.providers.cas.proxy.RejectProxyTickets"/>
+        </property>
+        <property name="ticketValidator">
+            <bean class="org.springframework.security.providers.cas.ticketvalidator.CasProxyTicketValidator">
+                <property name="casValidate" value="https://localhost:9443/cas/proxyValidate"/>
+                <property name="proxyCallbackUrl" value="https://localhost:8443/cas-sample/casProxy/receptor"/>
+                <property name="serviceProperties" ref="serviceProperties"/>
+                <property name="trustStore" value="../../certificates/server.jks"/>
+                <property name="trustPassword" value="password"/>
+                <!-- <property name="trustStore"><value>/some/path/to/your/lib/security/cacerts</value></property> -->
+            </bean>
+        </property>
+        <property name="statelessTicketCache">
+            <bean class="org.springframework.security.providers.cas.cache.EhCacheBasedTicketCache">
+                <property name="cache">
+                    <bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
+                        <property name="cacheManager">
+                            <bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
+                        </property>
+                        <property name="cacheName" value="ticketCache"/>
+                    </bean>
+                </property>
+            </bean>
+        </property>
+        <property name="key" value="an_id_for_this_auth_provider_only"/>
+    </bean>
+
+    <bean id="serviceProperties" class="org.springframework.security.ui.cas.ServiceProperties">
+        <property name="service" value="https://localhost:8443/cas-sample/j_spring_cas_security_check"/>
+        <property name="sendRenew" value="false"/>
+    </bean>
+
+    <sec:user-service id="userService">
+        <sec:user name="rod" password="rod" authorities="ROLE_SUPERVISOR,ROLE_USER" />
+        <sec:user name="dianne" password="dianne" authorities="ROLE_USER" />
+        <sec:user name="scott" password="scott" authorities="ROLE_USER" />
+    </sec:user-service>
+
+</beans>

+ 19 - 0
samples/cas/client/src/main/webapp/WEB-INF/classes/log4j.properties

@@ -0,0 +1,19 @@
+# Global logging configuration
+log4j.rootLogger=INFO, stdout, fileout
+
+log4j.logger.org.springframework.security=DEBUG, stdout, fileout
+
+# Console output...
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.conversionPattern=[%p,%c{1},%t] %m%n
+
+# Rolling log file output...
+log4j.appender.fileout=org.apache.log4j.RollingFileAppender
+log4j.appender.fileout.File=spring-security-cas-client.log
+log4j.appender.fileout.MaxFileSize=1024KB
+log4j.appender.fileout.MaxBackupIndex=1
+log4j.appender.fileout.layout=org.apache.log4j.PatternLayout
+log4j.appender.fileout.layout.conversionPattern=%d{ABSOLUTE} %5p %c{1},%t:%L - %m%n
+
+

+ 61 - 0
samples/cas/client/src/main/webapp/WEB-INF/web.xml

@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  - Tutorial web application
+  -
+  - $Id: web.xml 2476 2008-01-18 18:17:09Z luke_t $
+  -->
+
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
+
+    <display-name>Spring Security CAS Demo Application</display-name>
+
+    <!--
+	  - Location of the XML file that defines the root application context
+	  - Applied by ContextLoaderListener.
+	  -->
+	<context-param>
+		<param-name>contextConfigLocation</param-name>
+		<param-value>
+			/WEB-INF/applicationContext-security.xml
+		</param-value>
+	</context-param>
+
+    <context-param>
+        <param-name>log4jConfigLocation</param-name>
+        <param-value>/WEB-INF/classes/log4j.properties</param-value>
+    </context-param>
+
+    <filter>
+        <filter-name>_filterChainProxy</filter-name>
+        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
+    </filter>
+
+    <filter-mapping>
+      <filter-name>_filterChainProxy</filter-name>
+      <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
+	<!--
+	  - Loads the root application context of this web app at startup.
+	  - The application context is then available via
+	  - WebApplicationContextUtils.getWebApplicationContext(servletContext).
+    -->
+	<listener>
+		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+	</listener>
+
+    <listener>
+        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
+    </listener>    
+
+    <!--
+	  - Publishes events for session creation and destruction through the application
+	  - context. Optional unless concurrent session control is being used.
+      -->
+    <listener>
+      <listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>
+    </listener>
+
+</web-app>

+ 18 - 0
samples/cas/client/src/main/webapp/casfailed.jsp

@@ -0,0 +1,18 @@
+<%@ page import="org.springframework.security.AuthenticationException" %>
+<%@ page import="org.springframework.security.ui.AbstractProcessingFilter" %>
+
+<html>
+<head>
+    <title>Login to CAS failed!</title>
+</head>
+
+<body>
+<h2>Login to CAS failed!</h2>
+
+<font color="red">
+    Your CAS credentials were rejected.<br/><br/>
+    Reason: <%= ((AuthenticationException) session.getAttribute(AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY)).getMessage() %>
+</font>
+
+</body>
+</html>

+ 11 - 0
samples/cas/client/src/main/webapp/index.jsp

@@ -0,0 +1,11 @@
+<html>
+<body>
+<h1>Home Page</h1>
+<p>Anyone can view this page.</p>
+
+<p>Your principal object is....: <%= request.getUserPrincipal() %></p>
+
+<p><a href="secure/index.jsp">Secure page</a></p>
+<p><a href="secure/extreme/index.jsp">Extremely secure page</a></p>
+</body>
+</html>

+ 15 - 0
samples/cas/client/src/main/webapp/secure/extreme/index.jsp

@@ -0,0 +1,15 @@
+<%@ taglib prefix="authz" uri="http://www.springframework.org/security/tags" %>
+
+<html>
+<body>
+<h1>VERY Secure Page</h1>
+This is a protected page. You can only see me if you are a supervisor.
+
+<authz:authorize ifAllGranted="ROLE_SUPERVISOR">
+   You have "ROLE_SUPERVISOR" (this text is surrounded by &lt;authz:authorize&gt; tags).
+</authz:authorize>
+
+<p><a href="../../">Home</a>
+<p><a href="../../j_spring_security_logout">Logout</a>
+</body>
+</html>

+ 15 - 0
samples/cas/client/src/main/webapp/secure/index.jsp

@@ -0,0 +1,15 @@
+<html>
+<body>
+<h1>Secure Page</h1>
+This is a protected page. You can get to me if you've been remembered,
+or if you've authenticated this session.<br><br>
+
+<%if (request.isUserInRole("ROLE_SUPERVISOR")) { %>
+	You are a supervisor! You can therefore see the <a href="extreme/index.jsp">extremely secure page</a>.<br><br>
+<% } %>
+
+
+<p><a href="../">Home</a>
+<p><a href="../j_spring_security_logout">Logout</a>
+</body>
+</html>

+ 37 - 0
samples/cas/server/pom.xml

@@ -0,0 +1,37 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-samples</artifactId>
+        <version>2.0-SNAPSHOT</version>
+    </parent>
+    <groupId>org.springframework.security</groupId>
+    <artifactId>spring-security-samples-cas-server</artifactId>
+    <name>Spring Security - CAS Server for CAS Sample Application</name>
+    <packaging>pom</packaging>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.mortbay.jetty</groupId>
+                <artifactId>maven-jetty-plugin</artifactId>
+                <version>6.1.7</version>
+                <configuration>
+                    <contextPath>/cas</contextPath>
+                    <webApp>${basedir}/cas-server-webapp-3.1.1.war</webApp>
+                    <connectors>
+                        <connector implementation="org.mortbay.jetty.security.SslSocketConnector">
+                            <port>9443</port>
+                            <keystore>../../certificates/server.jks</keystore>
+                            <password>password</password>
+                            <keyPassword>password</keyPassword>
+                            <truststore>../../certificates/server.jks</truststore>
+                            <trustPassword>password</trustPassword>
+                            <wantClientAuth>true</wantClientAuth>
+                            <needClientAuth>false</needClientAuth>
+                        </connector>
+                    </connectors>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>