CAS一些配置项
下面是CAS-4.0.3服务端的来自cas.properties
中的一些配置项介绍
1、cas.securityContext.status.allowedSubnet=127.0.0.1
可以访问的服务端统计页面:http://sso.jadyer.com:8080/cas-server-web/status
可以访问的服务端统计页面:http://sso.jadyer.com:8080/cas-server-web/statistics
2、host.name=S3
uniqueIdGenerators.xml中的各种UniqueTicketIdGenerator生成TGT/ST等ticket时会用到host.name作为ticket的后缀
host.name通常用在集群环境下,其值对于每个节点来说都必须是唯一的,这样整个集群环境生成的各种ticket也必定是唯一的
单机环境下就没必要修改它了
3、slo.callbacks.disabled=false:是否禁用单点登出
4、cas.logout.followServiceRedirects=true:是否允许客户端Logout后重定向到service参数指定的资源
5、tgt.maxTimeToLiveInSeconds=28800:指定Session的最大有效时间,即从生成到指定时间后便超时,默认28800s,即8小时
6、tgt.timeToKillInSeconds=7200
指定用户操作的超时时间,即用户在多久不操作后就超时,默认7200s,即2小时
经本人亲测:在测试tgt.timeToKillInSeconds时还要注意客户端web.xml配置的超时时间
即只有客户端配置超时时间不大于tgt.timeToKillInSeconds时才能看见服务端设置的效果
7、st.timeToKillInSeconds=10
指定ServiceTicket的有效时间,默认10s
这也是debug追踪CAS应用认证过程中经常会失败的原因,因为追踪的时候ServiceTicket已经过了10秒有效期了
RememberMe原理
RememberMe也就是记住密码,可以让用户登录成功后,关闭浏览器再重新打开浏览器访问应用时不需要再次登录
实现方式可参考官方文档,网址如下(下面两个网址描述的都是一样的,只是第二个额外还有其它描述)
http://jasig.github.io/cas/development/installation/Configuring-LongTerm-Authentication.html
具体修改步骤如下
1、cas.properties中新增配置项rememberMeDuration=1209600
2、ticketExpirationPolicies.xml中新增RememberMe过期策略的配置
3、ticketGrantingTicketCookieGenerator.xml中新增属性项p:rememberMeMaxAge=”${rememberMeDuration:1209600}”
4、deployerConfigContext.xml
5、casLoginView.jsp表单中增加rememberMe字段
6、login-webflow.xml增加接收表单rememberMe字段的配置
7、UsernamePasswordCaptchaCredential.java集成RememberMeUsernamePasswordCredential使得可以接收表单的rememberMe字段
代码
本文源码下载:(下面两个地址的文件的内容,都是一样的,并包含了本系列的所有代码)
http://oirr30q6q.bkt.clouddn.com/jadyer/code/sso-cas-remember-me.rar
http://download.csdn.net/detail/jadyer/8940967
下面是ticketExpirationPolicies.xml
的修改
- <?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"/>
- <!-- TicketGrantingTicketExpirationPolicy: Default as of 3.5 -->
- <!-- Provides both idle and hard timeouts, for instance 2 hour sliding window with an 8 hour max lifetime -->
- <!--
- <bean id="grantingTicketExpirationPolicy" class="org.jasig.cas.ticket.support.TicketGrantingTicketExpirationPolicy"
- p:maxTimeToLiveInSeconds="${tgt.maxTimeToLiveInSeconds:28800}"
- p:timeToKillInSeconds="${tgt.timeToKillInSeconds:7200}"/>
- -->
- <!-- 以下为RememberMe所需配置 -->
- <!-- 这里要先把原有的<bean id="grantingTicketExpirationPolicy">注释掉,如上所示 -->
- <!-- 之所以注释是因为applicationContext.xml的第117行要用到<bean id="grantingTicketExpirationPolicy"> -->
- <!-- 而我们实现RememberMe需要用到的是RememberMeDelegatingExpirationPolicy,而非默认的TicketGrantingTicketExpirationPolicy -->
- <!-- 看看下面的配置就一目了然了 -->
- <!--
- | The following policy applies to standard CAS SSO sessions.
- | Default 2h (7200s) sliding expiration with default 8h (28800s) maximum lifetime.
- -->
- <bean id="standardSessionTGTExpirationPolicy" class="org.jasig.cas.ticket.support.TicketGrantingTicketExpirationPolicy"
- p:maxTimeToLiveInSeconds="${tgt.maxTimeToLiveInSeconds:28800}"
- p:timeToKillInSeconds="${tgt.timeToKillInSeconds:7200}"/>
- <!--
- | The following policy applies to long term CAS SSO sessions.
- | Default duration is two weeks (1209600s).
- -->
- <bean id="longTermSessionTGTExpirationPolicy" class="org.jasig.cas.ticket.support.TimeoutExpirationPolicy"
- c:timeToKillInMilliSeconds="#{ ${rememberMeDuration:1209600} * 1000 }"/>
- <bean id="grantingTicketExpirationPolicy" class="org.jasig.cas.ticket.support.RememberMeDelegatingExpirationPolicy"
- p:sessionExpirationPolicy-ref="standardSessionTGTExpirationPolicy"
- p:rememberMeExpirationPolicy-ref="longTermSessionTGTExpirationPolicy"/>
- </beans>
下面是cas.properties
中增加的rememberMeDuration配置
- # Long term authentication session length in seconds
- #服务端RememberMe的有效期,默认为1209600s,即两周
- rememberMeDuration=1209600
下面是ticketGrantingTicketCookieGenerator.xml
的修改
- <?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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>
- <!-- 针对RememberMe需增加p:rememberMeMaxAge属性配置 -->
- <bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
- p:cookieSecure="false"
- p:cookieMaxAge="-1"
- p:rememberMeMaxAge="${rememberMeDuration:1209600}"
- p:cookieName="CASTGC"
- p:cookiePath="/cas" />
- </beans>
下面是deployerConfigContext.xml
修改的部分
- <bean id="authenticationManager" class="org.jasig.cas.authentication.PolicyBasedAuthenticationManager">
- <constructor-arg>
- <map>
- <entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />
- <entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" />
- </map>
- </constructor-arg>
- <property name="authenticationPolicy">
- <bean class="org.jasig.cas.authentication.AnyAuthenticationPolicy" />
- </property>
- <!-- 针对RememberMe需增加的属性配置 -->
- <property name="authenticationMetaDataPopulators">
- <list>
- <bean class="org.jasig.cas.authentication.SuccessfulHandlerMetaDataPopulator"/>
- <bean class="org.jasig.cas.authentication.principal.RememberMeAuthenticationMetaDataPopulator"/>
- </list>
- </property>
- </bean>
下面是login-webflow.xml
修改的部分
- <view-state id="viewLoginForm" view="casLoginView" model="credential">
- <binder>
- <binding property="username"/>
- <binding property="password"/>
- <!-- 前台表单添加验证码字段captcha -->
- <binding property="captcha"/>
- <!-- 前台表单添加RememberMe字段 -->
- <binding property="rememberMe"/>
- </binder>
- <on-entry>
- <set name="viewScope.commandName" value="'credential'" />
- </on-entry>
- <transition on="submit" bind="true" validate="true" to="validateCaptcha">
- <evaluate expression="authenticationViaCaptchaFormAction.doBind(flowRequestContext, flowScope.credential)" />
- </transition>
- </view-state>
下面是UsernamePasswordCaptchaCredential.java
- package com.jadyer.sso.model;
- import org.jasig.cas.authentication.RememberMeUsernamePasswordCredential;
- /**
- * 自定义的接收登录验证码的实体类
- * Created by 玄玉<https://jadyer.github.io/> on 2015/07/14 16:28.
- */
- //public class UsernamePasswordCaptchaCredential extends UsernamePasswordCredential {
- public class UsernamePasswordCaptchaCredential extends RememberMeUsernamePasswordCredential {
- private static final long serialVersionUID = 8317889802836113837L;
- private String captcha;
- /*-- setter和getter略 --*/
- }
最后是/WEB-INF/view/jsp/jadyer/ui/casLoginView.jsp
- <%@ page pageEncoding="UTF-8"%>
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
- <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
- <c:set var="ctx" value="${pageContext.request.contextPath}" scope="session"/>
- <!DOCTYPE HTML>
- <html>
- <head>
- <meta charset="UTF-8"/>
- <title>CAS单点登录系统</title>
- <link rel="icon" type="image/x-icon" href="${ctx}/favicon.ico"/>
- <script type="text/javascript" src="${ctx}/js/jquery-1.10.2.min.js"></script>
- <script type="text/javascript" src="${ctx}/js/jquery-ui-1.10.2.min.js"></script>
- <script type="text/javascript" src="${ctx}/js/cas.js"></script>
- <!--[if lt IE 9]>
- <script src="${ctx}/js/html5shiv-3.7.2.min.js" type="text/javascript"></script>
- <![endif]-->
- </head>
- <style>
- body {background-color: #CBE0C9;}
- #msg {padding:20px; margin-bottom:10px;}
- #msg.errors {border:1px dotted #BB0000; color:#BB0000; padding-left:100px; background:url(${ctx}/images/error.gif) no-repeat 20px center;}
- </style>
- <body>
- <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>
- <form:form method="post" commandName="${commandName}" htmlEscape="true">
- <!--
- cssClass用于指定表单元素CSS样式名,相当于HTML元素的class属性
- cssStyle用于指定表单元素样式,相当于HTML元素的style属性
- cssErrorClass用于指定表单元素发生错误时对应的样式
- path属性用于绑定表单对象的属性值,它支持级联属性,比如path="user.userName"将调用表单对象getUser.getUserName()绑定表单对象的属性值
- -->
- <form:errors path="*" id="msg" cssClass="errors" element="div" htmlEscape="false"/>
- <input type="hidden" name="lt" value="${loginTicket}"/>
- <input type="hidden" name="execution" value="${flowExecutionKey}"/>
- <input type="hidden" name="_eventId" value="submit"/>
- <table border="9">
- <tr>
- <td>
- <c:if test="${not empty sessionScope.openIdLocalId}">
- <strong>${sessionScope.openIdLocalId}</strong>
- <input type="hidden" name="username" value="${sessionScope.openIdLocalId}"/>
- </c:if>
- <c:if test="${empty sessionScope.openIdLocalId}">
- <form:input tabindex="1" path="username" placeholder="帐号" htmlEscape="true" maxlength="16" size="25"/>
- </c:if>
- </td>
- </tr>
- <tr>
- <td>
- <form:password tabindex="2" path="password" placeholder="密码" htmlEscape="true" maxlength="16" size="25"/>
- </td>
- </tr>
- <tr>
- <td>
- <form:input tabindex="3" path="captcha" placeholder="验证码" htmlEscape="true" maxlength="4" size="15"/>
- <img style="cursor:pointer; vertical-align:middle;" src="captcha.jsp" onClick="this.src='captcha.jsp?time'+Math.random();">
- </td>
- </tr>
- <tr>
- <td>
- <input type="checkbox" tabindex="4" name="rememberMe" value="true"/>
- <label for="warn">RememberMe</label>
- </td>
- </tr>
- <!--
- <tr>
- <td>
- <input type="checkbox" tabindex="3" name="warn" value="true"/>
- <label for="warn">转向其他站点前提示我</label>
- </td>
- </tr>
- -->
- <tr>
- <td>
- <input type="submit" tabindex="5" value="登录"/>
- </td>
- </tr>
- </table>
- </form:form>
- </body>
- </html>