码迷,mamicode.com
首页 > 其他好文 > 详细

【试水CAS-4.0.3】第09节_CAS服务端RememberMe

时间:2015-07-28 21:10:04      阅读:865      评论:0      收藏:0      [点我收藏+]

标签:sso   cas   rememberme   记住密码   单点登录   

本文源码下载:http://download.csdn.net/detail/jadyer/8940967

/**
 * @see ------------------------------------------------------------------------------------------------------------------------
 * @see 先介绍一下CAS-4.0.3服务端的来自cas.properties中的一些其它配置项
 * @see 1.cas.securityContext.status.allowedSubnet=127.0.0.1
 * @see   可以访问的服务端统计页面:http://sso.jadyer.com:8080/cas-server-web/status
 * @see   可以访问的服务端统计页面:http://sso.jadyer.com:8080/cas-server-web/statistics
 * @see 2.host.name=S3
 * @see   uniqueIdGenerators.xml中的各种UniqueTicketIdGenerator生成TGT/ST等ticket时会用到host.name作为ticket的后缀
 * @see   host.name通常用在集群环境下,其值对于每个节点来说都必须是唯一的,这样整个集群环境生成的各种ticket也必定是唯一的
 * @see   单机环境下就没必要修改它了
 * @see 3.cas.logout.followServiceRedirects=true
 * @see   是否允许客户端Logout后重定向到service参数指定的资源
 * @see 4.tgt.maxTimeToLiveInSeconds=28800
 * @see   指定Session的最大有效时间,即从生成到指定时间后就将超时,默认28800s,即8小时
 * @see 5.tgt.timeToKillInSeconds=7200
 * @see   指定用户操作的超时时间,即用户在多久不操作后就超时,默认7200s,即2小时
 * @see   经本人亲测:在测试tgt.timeToKillInSeconds时还要注意客户端web.xml配置的超时时间
 * @see   即只有客户端配置超时时间不大于tgt.timeToKillInSeconds时才能看见服务端设置的效果
 * @see 6.st.timeToKillInSeconds=10
 * @see   指定service ticket的有效时间,默认10s
 * @see   这也是debug追踪CAS应用认证过程中经常会失败的原因,因为追踪的时候service ticket已经过了10秒有效期了
 * @see 7.slo.callbacks.disabled=false
 * @see   是否禁用单点登出
 * @see ------------------------------------------------------------------------------------------------------------------------
 * @create 2015-7-28 下午7:49:24
 * @author 玄玉<http://blog.csdn.net/jadyer>
 */

下面是关于启用RememberMe功能所需做的修改描述

/**
 * @see CAS服务端RememberMe
 * @see ------------------------------------------------------------------------------------------------------------------------
 * @see 关于RememberMe,可参考官方文档,网址如下(下面两个网址描述的RememberMe实现都是一样的,只是第二个还有其它描述)
 * @see http://jasig.github.io/cas/development/installation/Configuring-LongTerm-Authentication.html
 * @see http://jasig.github.io/cas/4.0.x/installation/Configuring-Authentication-Components.html#long-term-authentication
 * @see RememberMe也就是平时所说的记住密码的功能,可以让用户登录成功后,关闭浏览器再重新打开浏览器访问应用时不需要再次登录
 * @see RememberMe与上面的Session超时配置tgt.timeToKillInSeconds是两回事,Session超时是针对一次会话而言,RememberMe则更广
 * @see 另外本文的CAS-4.0.3服务端源码修改,是在我的以下三篇博文基础上修改的,最终我会在CSDN上提供整体源码下载
 * @see http://blog.csdn.net/jadyer/article/details/46875393
 * @see http://blog.csdn.net/jadyer/article/details/46914661
 * @see http://blog.csdn.net/jadyer/article/details/46916169
 * @see 具体修改步骤如下
 * @see 1.cas.properties中新增配置项rememberMeDuration=1209600
 * @see 2.ticketExpirationPolicies.xml中新增RememberMe过期策略的配置
 * @see 3.ticketGrantingTicketCookieGenerator.xml中新增属性项p:rememberMeMaxAge="${rememberMeDuration:1209600}"
 * @see 4.deployerConfigContext.xml
 * @see 5.casLoginView.jsp表单中增加rememberMe字段
 * @see 6.login-webflow.xml增加接收表单rememberMe字段的配置
 * @see 7.UsernamePasswordCaptchaCredential.java集成RememberMeUsernamePasswordCredential使得可以接收表单的rememberMe字段
 * @see ------------------------------------------------------------------------------------------------------------------------
 * @create 2015-7-28 下午7:58:08
 * @author 玄玉<http://blog.csdn.net/jadyer>
 */
下面是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>
下面是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.msxf.sso.model;

import org.jasig.cas.authentication.RememberMeUsernamePasswordCredential;

/**
 * 自定义的接收登录验证码的实体类
 * @create 2015-7-14 下午4:28:33
 * @author 玄玉<http://blog.csdn.net/jadyer>
 */
//public class UsernamePasswordCaptchaCredential extends UsernamePasswordCredential {
public class UsernamePasswordCaptchaCredential extends RememberMeUsernamePasswordCredential {
	private static final long serialVersionUID = 8317889802836113837L;
	
	private String captcha;

	public String getCaptcha() {
		return captcha;
	}

	public void setCaptcha(String captcha) {
		this.captcha = captcha;
	}
}
下面是//WEB-INF//view//jsp//msxf//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>
最后是cas.properties中增加的rememberMeDuration配置
# Long term authentication session length in seconds
#服务端RememberMe的有效期,默认为1209600s,即两周
rememberMeDuration=1209600

验证RememberMe功能是否成功的办法就是:用客户端单点登录成功后,关掉浏览器,再打开浏览器访问客户端,此时若不登录就能访问成功说明RememberMe成功!!

版权声明:本文为博主原创文章,未经博主允许不得转载。

【试水CAS-4.0.3】第09节_CAS服务端RememberMe

标签:sso   cas   rememberme   记住密码   单点登录   

原文地址:http://blog.csdn.net/jadyer/article/details/47110353

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!