cas-shiro-demo

This commit is contained in:
雪山飞鹄
2014-07-12 22:42:51 +08:00
parent 20ddb65c72
commit af5b4bac3d
19 changed files with 764 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
.classpath
.project
.settings/
target/
test-output/
bin/
+22
View File
@@ -0,0 +1,22 @@
h2. What is this project ?
This project *cas-shiro-demo* has been created to test the CAS support for Shiro library, i.e. the *shiro-cas* library. It’s composed of two modules :
- the *cas-shiro-demo-app* module is a demo web application which uses the CAS Shiro support library with protected area requiring CAS authentication : "http://shiro.apache.org/cas.html":http://shiro.apache.org/cas.html
- the *cas-shiro-demo-server* module is a CAS server configured with remember-me feature.
h2. Quick start & test
To start quickly, build the project :<pre><code>cas-shiro-demo
mvn clean install</code></pre>and start the two web applications with jetty :<pre><code>cd cas-shiro-demo-app
mvn jetty:run</code></pre>
To test,
- call the "http://localhost:8080/app/user/index.jsp":http://localhost:8080/app/user/index.jsp url by clicking on the _user/index_ link
- be sent to CAS server and log in (the password is equal to the login)
- be redirected back to the application, authenticated.
h2. Manual deployment
You can also deploy manually these two web applications in your favorite web applications server :
- cas-shiro-demo-app on http://localhost:8080/app
- cas-shiro-demo-server on http://localhost:8080/cas
@@ -0,0 +1,6 @@
.classpath
.project
.settings/
target/
test-output/
bin/
+74
View File
@@ -0,0 +1,74 @@
<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.leleuj</groupId>
<artifactId>cas-shiro-demo</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>cas-shiro-demo-app</artifactId>
<packaging>war</packaging>
<name>CAS Shiro demo : application</name>
<description>CAS Shiro demo : application</description>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-cas</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.opensaml</groupId>
<artifactId>opensaml</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.apache.santuario</groupId>
<artifactId>xmlsec</artifactId>
<version>1.4.3</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.7.v20120910</version>
<configuration>
<webApp>
<contextPath>/app</contextPath>
</webApp>
<contextHandlers>
<contextHandler implementation="org.eclipse.jetty.webapp.WebAppContext">
<war>${basedir}/../cas-shiro-demo-server/target/cas-shiro-demo-server.war</war>
<contextPath>/cas</contextPath>
</contextHandler>
</contextHandlers>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,7 @@
log4j.rootLogger=WARN, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=CAS SHIRO DEMO APP %d{yyyy/MM/dd HH:mm:ss,SSS} %5p [%t] %c - %m%n
log4j.logger.org.apache.shiro=DEBUG
@@ -0,0 +1,26 @@
[main]
casFilter = org.apache.shiro.cas.CasFilter
casFilter.failureUrl = /error.jsp
casRealm = org.apache.shiro.cas.CasRealm
casRealm.defaultRoles = ROLE_USER
casRealm.casServerUrlPrefix = http://localhost:8080/cas/
casRealm.casService = http://localhost:8080/app/shiro-cas
casRealm.validationProtocol = SAML
casSubjectFactory = org.apache.shiro.cas.CasSubjectFactory
securityManager.subjectFactory = $casSubjectFactory
# only with SHIRO-373 featured added :
#casAuthUser = org.apache.shiro.cas.CasAuthenticatedUserFilter
#casAuthUser.loginUrl = http://localhost:8080/cas/login?service=http://localhost:8080/app/shiro-cas
user.loginUrl = http://localhost:8080/cas/login?service=http://localhost:8080/app/shiro-cas
[urls]
/shiro-cas = casFilter
# only with SHIRO-373 featured added :
#/auth/** = casAuthUser
/user/** = user
/logout = logout
/** = anon
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<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>CAS Shiro demo : application</display-name>
<filter>
<filter-name>ShiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ShiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
@@ -0,0 +1,12 @@
<h1>auth/index</h1>
<a href="/app/logout">logout</a><br />
<br />
<%@page import="org.apache.shiro.subject.Subject"%>
<%@page import="org.apache.shiro.SecurityUtils"%>
<%
Subject subject = SecurityUtils.getSubject();
%>
principal : <%=subject.getPrincipal()%><br />
principals : <%=subject.getPrincipals()%><br />
isAuthenticated : <%=subject.isAuthenticated()%><br />
isRemembered : <%=subject.isRemembered()%><br />
@@ -0,0 +1 @@
<h1>error</h1>
@@ -0,0 +1,2 @@
<a href="auth/index.jsp">auth/index</a><br />
<a href="user/index.jsp">user/index</a><br />
@@ -0,0 +1,12 @@
<h1>user/index</h1>
<a href="/app/logout">logout</a><br />
<br />
<%@page import="org.apache.shiro.subject.Subject"%>
<%@page import="org.apache.shiro.SecurityUtils"%>
<%
Subject subject = SecurityUtils.getSubject();
%>
principal : <%=subject.getPrincipal()%><br />
principals : <%=subject.getPrincipals()%><br />
isAuthenticated : <%=subject.isAuthenticated()%><br />
isRemembered : <%=subject.isRemembered()%><br />
@@ -0,0 +1,6 @@
.classpath
.project
.settings/
target/
test-output/
bin/
@@ -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.leleuj</groupId>
<artifactId>cas-shiro-demo</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>cas-shiro-demo-server</artifactId>
<packaging>war</packaging>
<name>CAS Shiro demo : CAS server</name>
<description>CAS Shiro demo : CAS server</description>
<dependencies>
<dependency>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-server-webapp</artifactId>
<version>${cas.version}</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
</plugin>
</plugins>
</build>
<properties>
<cas.version>3.5.0</cas.version>
</properties>
</project>
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<bean id="authenticationManager" class="org.jasig.cas.authentication.AuthenticationManagerImpl">
<property name="authenticationMetaDataPopulators">
<list>
<bean class="org.jasig.cas.authentication.principal.RememberMeAuthenticationMetaDataPopulator" />
</list>
</property>
<property name="credentialsToPrincipalResolvers">
<list>
<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" />
<bean class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" />
</list>
</property>
<property name="authenticationHandlers">
<list>
<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" p:httpClient-ref="httpClient" />
<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
</list>
</property>
</bean>
<sec:user-service id="userDetailsService">
<sec:user name="@@THIS SHOULD BE REPLACED@@" password="notused" authorities="ROLE_ADMIN" />
</sec:user-service>
<bean id="attributeRepository" class="org.jasig.services.persondir.support.StubPersonAttributeDao">
<property name="backingMap">
<map>
<entry key="uid" value="uid" />
<entry key="eduPersonAffiliation" value="eduPersonAffiliation" />
<entry key="groupMembership" value="groupMembership" />
</map>
</property>
</bean>
<bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl">
<property name="registeredServices">
<list>
<bean class="org.jasig.cas.services.RegexRegisteredService">
<property name="id" value="0" />
<property name="name" value="HTTP and IMAP" />
<property name="description" value="Allows HTTP(S) and IMAP(S) protocols" />
<property name="serviceId" value="^(https?|imaps?)://.*" />
<property name="evaluationOrder" value="10000001" />
</bean>
<!-- Use the following definition instead of the above to further restrict access to services within your domain (including subdomains). Note that example.com must be replaced with the domain you wish to permit. -->
<!-- <bean class="org.jasig.cas.services.RegexRegisteredService"> <property name="id" value="1" /> <property name="name" value="HTTP and IMAP on example.com" /> <property name="description" value="Allows HTTP(S) and IMAP(S) protocols on example.com" /> <property name="serviceId"
value="^(https?|imaps?)://([A-Za-z0-9_-]+\.)*example\.com/.*" /> <property name="evaluationOrder" value="0" /> </bean> -->
</list>
</property>
</bean>
<bean id="auditTrailManager" class="com.github.inspektr.audit.support.Slf4jLoggingAuditTrailManager" />
<bean id="healthCheckMonitor" class="org.jasig.cas.monitor.HealthCheckMonitor">
<property name="monitors">
<list>
<bean class="org.jasig.cas.monitor.MemoryMonitor" p:freeMemoryWarnThreshold="10" />
<bean class="org.jasig.cas.monitor.SessionMonitor" p:ticketRegistry-ref="ticketRegistry" p:serviceTicketCountWarnThreshold="5000" p:sessionCountWarnThreshold="100000" />
</list>
</property>
</bean>
</beans>
@@ -0,0 +1,217 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to Jasig under one or more contributor license
~ agreements. See the NOTICE file distributed with this work
~ for additional information regarding copyright ownership.
~ Jasig licenses this file to you 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 the following location:
~
~ 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.
-->
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<var name="credentials" class="org.jasig.cas.authentication.principal.RememberMeUsernamePasswordCredentials" />
<on-start>
<evaluate expression="initialFlowSetupAction" />
</on-start>
<decision-state id="ticketGrantingTicketExistsCheck">
<if test="flowScope.ticketGrantingTicketId != null" then="hasServiceCheck" else="gatewayRequestCheck" />
</decision-state>
<decision-state id="gatewayRequestCheck">
<if test="requestParameters.gateway != '' and requestParameters.gateway != null and flowScope.service != null" then="gatewayServicesManagementCheck" else="generateLoginTicket" />
</decision-state>
<decision-state id="hasServiceCheck">
<if test="flowScope.service != null" then="renewRequestCheck" else="viewGenericLoginSuccess" />
</decision-state>
<decision-state id="renewRequestCheck">
<if test="requestParameters.renew != '' and requestParameters.renew != null" then="generateLoginTicket" else="generateServiceTicket" />
</decision-state>
<!--
The "warn" action makes the determination of whether to redirect directly to the requested
service or display the "confirmation" page to go back to the server.
-->
<decision-state id="warn">
<if test="flowScope.warnCookieValue" then="showWarningView" else="redirect" />
</decision-state>
<!--
<action-state id="startAuthenticate">
<action bean="x509Check" />
<transition on="success" to="sendTicketGrantingTicket" />
<transition on="warn" to="warn" />
<transition on="error" to="generateLoginTicket" />
</action-state>
-->
<!--
LPPE transitions begin here: You will also need to
move over the 'lppe-configuration.xml' file from the
'unused-spring-configuration' folder to the 'spring-configuration' folder
so CAS can pick up the definition for the bean 'passwordPolicyAction'.
-->
<action-state id="passwordPolicyCheck">
<evaluate expression="passwordPolicyAction" />
<transition on="showWarning" to="passwordServiceCheck" />
<transition on="success" to="sendTicketGrantingTicket" />
<transition on="error" to="viewLoginForm" />
</action-state>
<action-state id="passwordServiceCheck">
<evaluate expression="sendTicketGrantingTicketAction" />
<transition to="passwordPostCheck" />
</action-state>
<decision-state id="passwordPostCheck">
<if test="flowScope.service != null" then="warnPassRedirect" else="pwdWarningPostView" />
</decision-state>
<action-state id="warnPassRedirect">
<evaluate expression="generateServiceTicketAction" />
<transition on="success" to="pwdWarningPostView" />
<transition on="error" to="generateLoginTicket" />
<transition on="gateway" to="gatewayServicesManagementCheck" />
</action-state>
<end-state id="pwdWarningAbstractView">
<on-entry>
<set name="flowScope.passwordPolicyUrl" value="passwordPolicyAction.getPasswordPolicyUrl()" />
</on-entry>
</end-state>
<end-state id="pwdWarningPostView" view="casWarnPassView" parent="#pwdWarningAbstractView" />
<end-state id="casExpiredPassView" view="casExpiredPassView" parent="#pwdWarningAbstractView" />
<end-state id="casMustChangePassView" view="casMustChangePassView" parent="#pwdWarningAbstractView" />
<end-state id="casAccountDisabledView" view="casAccountDisabledView" />
<end-state id="casAccountLockedView" view="casAccountLockedView" />
<end-state id="casBadHoursView" view="casBadHoursView" />
<end-state id="casBadWorkstationView" view="casBadWorkstationView" />
<!-- LPPE transitions end here... -->
<action-state id="generateLoginTicket">
<evaluate expression="generateLoginTicketAction.generate(flowRequestContext)" />
<transition on="generated" to="viewLoginForm" />
</action-state>
<view-state id="viewLoginForm" view="casLoginView" model="credentials">
<binder>
<binding property="username" />
<binding property="password" />
<binding property="rememberMe" />
</binder>
<on-entry>
<set name="viewScope.commandName" value="'credentials'" />
</on-entry>
<transition on="submit" bind="true" validate="true" to="realSubmit">
<evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credentials)" />
</transition>
</view-state>
<action-state id="realSubmit">
<evaluate expression="authenticationViaFormAction.submit(flowRequestContext, flowScope.credentials, messageContext)" />
<!--
To enable LPPE on the 'warn' replace the below transition with:
<transition on="warn" to="passwordPolicyCheck" />
CAS will attempt to transition to the 'warn' when there's a 'renew' parameter
and there exists a ticketGrantingId and a service for the incoming request.
-->
<transition on="warn" to="warn" />
<!--
To enable LPPE on the 'success' replace the below transition with:
<transition on="success" to="passwordPolicyCheck" />
-->
<transition on="success" to="sendTicketGrantingTicket" />
<transition on="error" to="generateLoginTicket" />
<transition on="accountDisabled" to="casAccountDisabledView" />
<transition on="mustChangePassword" to="casMustChangePassView" />
<transition on="accountLocked" to="casAccountLockedView" />
<transition on="badHours" to="casBadHoursView" />
<transition on="badWorkstation" to="casBadWorkstationView" />
<transition on="passwordExpired" to="casExpiredPassView" />
</action-state>
<action-state id="sendTicketGrantingTicket">
<evaluate expression="sendTicketGrantingTicketAction" />
<transition to="serviceCheck" />
</action-state>
<decision-state id="serviceCheck">
<if test="flowScope.service != null" then="generateServiceTicket" else="viewGenericLoginSuccess" />
</decision-state>
<action-state id="generateServiceTicket">
<evaluate expression="generateServiceTicketAction" />
<transition on="success" to ="warn" />
<transition on="error" to="generateLoginTicket" />
<transition on="gateway" to="gatewayServicesManagementCheck" />
</action-state>
<action-state id="gatewayServicesManagementCheck">
<evaluate expression="gatewayServicesManagementCheck" />
<transition on="success" to="redirect" />
</action-state>
<action-state id="redirect">
<evaluate expression="flowScope.service.getResponse(requestScope.serviceTicketId)" result-type="org.jasig.cas.authentication.principal.Response" result="requestScope.response" />
<transition to="postRedirectDecision" />
</action-state>
<decision-state id="postRedirectDecision">
<if test="requestScope.response.responseType.name() == 'POST'" then="postView" else="redirectView" />
</decision-state>
<!--
the "viewGenericLogin" is the end state for when a user attempts to login without coming directly from a service.
They have only initialized their single-sign on session.
-->
<end-state id="viewGenericLoginSuccess" view="casLoginGenericSuccessView" />
<!--
The "showWarningView" end state is the end state for when the user has requested privacy settings (to be "warned") to be turned on. It delegates to a
view defines in default_views.properties that display the "Please click here to go to the service." message.
-->
<end-state id="showWarningView" view="casLoginConfirmView" />
<end-state id="postView" view="postResponseView">
<on-entry>
<set name="requestScope.parameters" value="requestScope.response.attributes" />
<set name="requestScope.originalUrl" value="flowScope.service.id" />
</on-entry>
</end-state>
<!--
The "redirect" end state allows CAS to properly end the workflow while still redirecting
the user back to the service required.
-->
<end-state id="redirectView" view="externalRedirect:${requestScope.response.url}" />
<end-state id="viewServiceErrorView" view="viewServiceErrorView" />
<end-state id="viewServiceSsoErrorView" view="viewServiceSsoErrorView" />
<global-transitions>
<!-- CAS-1023 This one is simple - redirects to a login page (same as renew) when 'ssoEnabled' flag is unchecked
instead of showing an intermediate unauthorized view with a link to login page -->
<transition to="viewLoginForm" on-exception="org.jasig.cas.services.UnauthorizedSsoServiceException"/>
<transition to="viewServiceErrorView" on-exception="org.springframework.webflow.execution.repository.NoSuchFlowExecutionException" />
<transition to="viewServiceErrorView" on-exception="org.jasig.cas.services.UnauthorizedServiceException" />
</global-transitions>
</flow>
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- ~ Licensed to Jasig under one or more contributor license ~ agreements. See the NOTICE file distributed with this work ~ for additional information regarding copyright ownership. ~ Jasig licenses this file to you 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 the following location: ~ ~ 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. -->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<description>
Assignment of expiration policies for the different tickets generated by CAS including ticket granting ticket
(TGT), service ticket (ST), proxy granting ticket (PGT), and proxy ticket (PT).
These expiration policies determine how long the ticket they are assigned
to can be used and even how often they
can be used before becoming expired / invalid.
</description>
<!-- Expiration policies -->
<util:constant id="SECONDS" static-field="java.util.concurrent.TimeUnit.SECONDS" />
<bean id="serviceTicketExpirationPolicy" class="org.jasig.cas.ticket.support.MultiTimeUseOrTimeoutExpirationPolicy" c:numberOfUses="1" c:timeToKill="${st.timeToKillInSeconds:10}" c:timeUnit-ref="SECONDS" />
<bean id="grantingTicketExpirationPolicy" class="org.jasig.cas.ticket.support.RememberMeDelegatingExpirationPolicy">
<property name="sessionExpirationPolicy">
<bean class="org.jasig.cas.ticket.support.TimeoutExpirationPolicy">
<constructor-arg index="0" value="7200000" />
</bean>
</property>
<property name="rememberMeExpirationPolicy">
<bean class="org.jasig.cas.ticket.support.TimeoutExpirationPolicy">
<constructor-arg index="0" value="3600000000" />
</bean>
</property>
</bean>
</beans>
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to Jasig under one or more contributor license
~ agreements. See the NOTICE file distributed with this work
~ for additional information regarding copyright ownership.
~ Jasig licenses this file to you 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 the following location:
~
~ 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.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<description>
Defines the cookie that stores the TicketGrantingTicket. You most likely should never modify these (especially the "secure" property).
You can change the name if you want to make it harder for people to guess.
</description>
<bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
p:cookieSecure="false"
p:cookieMaxAge="-1"
p:cookieName="CASTGC"
p:cookiePath="/cas" />
</beans>
@@ -0,0 +1,143 @@
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
~ Licensed to Jasig under one or more contributor license
~ agreements. See the NOTICE file distributed with this work
~ for additional information regarding copyright ownership.
~ Jasig licenses this file to you 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 the following location:
~
~ 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.
--%>
<%@ page contentType="text/html; charset=UTF-8" %>
<jsp:directive.include file="includes/top.jsp" />
<c:if test="${not pageContext.request.secure}">
<div id="msg" class="errors">
<h2>Non-secure Connection</h2>
<p>You are currently accessing CAS over a non-secure connection. Single Sign On WILL NOT WORK. In order to have single sign on work, you MUST log in over HTTPS.</p>
</div>
</c:if>
<div class="box fl-panel" id="login">
<form:form method="post" id="fm1" cssClass="fm-v clearfix" commandName="${commandName}" htmlEscape="true">
<form:errors path="*" id="msg" cssClass="errors" element="div" />
<!-- <spring:message code="screen.welcome.welcome" /> -->
<h2><spring:message code="screen.welcome.instructions" /></h2>
<div class="row fl-controls-left">
<label for="username" class="fl-label"><spring:message code="screen.welcome.label.netid" /></label>
<c:if test="${not empty sessionScope.openIdLocalId}">
<strong>${sessionScope.openIdLocalId}</strong>
<input type="hidden" id="username" name="username" value="${sessionScope.openIdLocalId}" />
</c:if>
<c:if test="${empty sessionScope.openIdLocalId}">
<spring:message code="screen.welcome.label.netid.accesskey" var="userNameAccessKey" />
<form:input cssClass="required" cssErrorClass="error" id="username" size="25" tabindex="1" accesskey="${userNameAccessKey}" path="username" autocomplete="false" htmlEscape="true" />
</c:if>
</div>
<div class="row fl-controls-left">
<label for="password" class="fl-label"><spring:message code="screen.welcome.label.password" /></label>
<%--
NOTE: Certain browsers will offer the option of caching passwords for a user. There is a non-standard attribute,
"autocomplete" that when set to "off" will tell certain browsers not to prompt to cache credentials. For more
information, see the following web page:
http://www.geocities.com/technofundo/tech/web/ie_autocomplete.html
--%>
<spring:message code="screen.welcome.label.password.accesskey" var="passwordAccessKey" />
<form:password cssClass="required" cssErrorClass="error" id="password" size="25" tabindex="2" path="password" accesskey="${passwordAccessKey}" htmlEscape="true" autocomplete="off" />
</div>
<div class="row check">
<input id="warn" name="warn" value="true" tabindex="3" accesskey="<spring:message code="screen.welcome.label.warn.accesskey" />" type="checkbox" />
<label for="warn"><spring:message code="screen.welcome.label.warn" /></label>
</div>
<div class="row check">
<input id="rememberMe" name="rememberMe" value="true" tabindex="4" type="checkbox" />
<label for="rememberMe">Remember-me</label>
</div>
<div class="row btn-row">
<input type="hidden" name="lt" value="${loginTicket}" />
<input type="hidden" name="execution" value="${flowExecutionKey}" />
<input type="hidden" name="_eventId" value="submit" />
<input class="btn-submit" name="submit" accesskey="l" value="<spring:message code="screen.welcome.button.login" />" tabindex="4" type="submit" />
<input class="btn-reset" name="reset" accesskey="c" value="<spring:message code="screen.welcome.button.clear" />" tabindex="5" type="reset" />
</div>
</form:form>
</div>
<div id="sidebar">
<p class="fl-panel fl-note fl-bevel-white fl-font-size-80"><spring:message code="screen.welcome.security" /></p>
<div id="list-languages" class="fl-panel">
<%final String queryString = request.getQueryString() == null ? "" : request.getQueryString().replaceAll("&locale=([A-Za-z][A-Za-z]_)?[A-Za-z][A-Za-z]|^locale=([A-Za-z][A-Za-z]_)?[A-Za-z][A-Za-z]", "");%>
<c:set var='query' value='<%=queryString%>' />
<c:set var="xquery" value="${fn:escapeXml(query)}" />
<h3>Languages:</h3>
<c:choose>
<c:when test="${not empty requestScope['isMobile'] and not empty mobileCss}">
<form method="get" action="login?${xquery}">
<select name="locale">
<option value="en">English</option>
<option value="es">Spanish</option>
<option value="fr">French</option>
<option value="ru">Russian</option>
<option value="nl">Nederlands</option>
<option value="sv">Svenskt</option>
<option value="it">Italiano</option>
<option value="ur">Urdu</option>
<option value="zh_CN">Chinese (Simplified)</option>
<option value="zh_TW">Chinese (Traditional)</option>
<option value="de">Deutsch</option>
<option value="ja">Japanese</option>
<option value="hr">Croatian</option>
<option value="cs">Czech</option>
<option value="sl">Slovenian</option>
<option value="pl">Polish</option>
<option value="ca">Catalan</option>
<option value="mk">Macedonian</option>
<option value="fa">Farsi</option>
<option value="ar">Arabic</option>
</select>
<input type="submit" value="Switch">
</form>
</c:when>
<c:otherwise>
<c:set var="loginUrl" value="login?${xquery}${not empty xquery ? '&' : ''}locale=" />
<ul
><li class="first"><a href="${loginUrl}en">English</a></li
><li><a href="${loginUrl}es">Spanish</a></li
><li><a href="${loginUrl}fr">French</a></li
><li><a href="${loginUrl}ru">Russian</a></li
><li><a href="${loginUrl}nl">Nederlands</a></li
><li><a href="${loginUrl}sv">Svenskt</a></li
><li><a href="${loginUrl}it">Italiano</a></li
><li><a href="${loginUrl}ur">Urdu</a></li
><li><a href="${loginUrl}zh_CN">Chinese (Simplified)</a></li
><li><a href="${loginUrl}zh_TW">Chinese (Traditional)</a></li
><li><a href="${loginUrl}de">Deutsch</a></li
><li><a href="${loginUrl}ja">Japanese</a></li
><li><a href="${loginUrl}hr">Croatian</a></li
><li><a href="${loginUrl}cs">Czech</a></li
><li><a href="${loginUrl}sl">Slovenian</a></li
><li><a href="${loginUrl}ca">Catalan</a></li
><li><a href="${loginUrl}mk">Macedonian</a></li
><li><a href="${loginUrl}fa">Farsi</a></li
><li><a href="${loginUrl}ar">Arabic</a></li
><li class="last"><a href="${loginUrl}pl">Polish</a></li
></ul>
</c:otherwise>
</c:choose>
</div>
</div>
<jsp:directive.include file="includes/bottom.jsp" />
+37
View File
@@ -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>
<groupId>org.leleuj</groupId>
<artifactId>cas-shiro-demo</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>CAS Shiro demo</name>
<description>CAS Shiro demo</description>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.7</version>
<configuration>
<wtpversion>2.0</wtpversion>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<modules>
<module>cas-shiro-demo-app</module>
<module>cas-shiro-demo-server</module>
</modules>
</project>