• Category Archives: SSO

通过正则表达式在中设置不包含的页面

比如写如下的配置文:
<filter-mapping>
<filter-name>AdminFilter</filter-name>
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
那么admin目录下所有的文件都将在访问前被过滤器拦截,包括login.jsp。

我们可以自己在 Filter 里用正则表达式进行二次过滤,过滤的正则表达式可以通过:

<filter>
	<filter-name>LoginFilter</filter-name>
	<filter-class>com.test.LoginFilter</filter-class>
	<init-param>
		<param-name>UrlRegx</param-name>
		<param-value><!--你的正则表达式--></param-value>
	</init-param>
</filter>

 

CAS返回更多用户信息

1.修改deployerConfigContext.xml文件

 

2.修改casServiceValidationSuccess.jsp文件

 

 

 

 

3.最后修改client端的web.xml文件:

	<!-- ======================== 单点登录开始 ======================== -->
	<!-- 用于单点退出,该过滤器用于实现单点登出功能,可选配置 -->
	<listener>
		<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
	</listener>
	<filter>
		<filter-name>CAS Single Sign Out Filter</filter-name>
		<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>CAS Single Sign Out Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<filter>
		<filter-name>CAS Filter</filter-name>
		<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
		<init-param>
			<param-name>casServerLoginUrl</param-name>
			<param-value>http://localhost:8080/cas</param-value>
		</init-param>
		<init-param>
			<param-name>serverName</param-name>
			<param-value>http://localhost:8080</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CAS Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- 该过滤器负责对Ticket的校验工作,必须启用它 -->
	<filter>
		<filter-name>CAS Validation Filter</filter-name>
		<filter-class>
			org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter
		</filter-class>
		<init-param>
			<param-name>casServerUrlPrefix</param-name>
			<param-value>http://localhost:8080/cas</param-value>
		</init-param>
		<init-param>
			<param-name>serverName</param-name>
			<param-value>http://localhost:8080</param-value>
		</init-param>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CAS Validation Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- 该过滤器负责实现HttpServletRequest请求的包裹, -->
	<!-- 比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。 -->

	<filter>
		<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
		<filter-class>
			org.jasig.cas.client.util.HttpServletRequestWrapperFilter
		</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- 该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。 -->
	<!-- 比如AssertionHolder.getAssertion().getPrincipal().getName()。根据客户端获取的方式可以选择使用这两种 -->


	<!-- <filter> <filter-name>CAS Assertion Thread Local Filter</filter-name> 
		<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class> 
		</filter> <filter-mapping> <filter-name>CAS Assertion Thread Local Filter</filter-name> 
		<url-pattern>/*</url-pattern> </filter-mapping> -->

	<!-- ======================== 单点登录结束 ======================== -->

4.可以用以下jsp代码来验证是否成功获取用户的更多信息:

	<%
	out.write("request.getUserPrincipal()="+request.getUserPrincipal());
	%>
	
	<br/><br/>


<%
//HttpServletRequest request = ServletActionContext.getRequest();
/*获取单点登录服务器传递过来的用户信息*/
AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();
if (principal!=null) {
	out.write("principal不为空...");
	Map<String, Object> attributes = principal.getAttributes();
	for (String key : attributes.keySet()) {
		System.out.println(key+"="+attributes.get(key));
	}
}else{
	out.write("principal为空...");
}
%>

 

取消CAS的HTTPS登陆

1、修改WEB-INF\deployerConfigContext.xml,加入

 p:requireSecure="false"

<property name="authenticationHandlers">
			<list>
				<!--
					| This is the authentication handler that authenticates services by means of callback via SSL, thereby validating
					| a server side SSL certificate.
					+-->
				<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
					p:httpClient-ref="httpClient" p:requireSecure="false"/>
				<!--
					| This is the authentication handler declaration that every CAS deployer will need to change before deploying CAS 
					| into production.  The default SimpleTestUsernamePasswordAuthenticationHandler authenticates UsernamePasswordCredentials
					| where the username equals the password.  You will need to replace this with an AuthenticationHandler that implements your
					| local authentication strategy.  You might accomplish this by coding a new such handler and declaring
					| edu.someschool.its.cas.MySpecialHandler here, or you might use one of the handlers provided in the adaptors modules.
					+-->
				<bean
					class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
			</list>
		</property>

2、修改WEB-INF\spring-configuration\ticketGrantingTicketCookieGenerator.xml,修改p:cookieSecure=”false”

	<bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
		p:cookieSecure="false"
		p:cookieMaxAge="-1"
		p:cookieName="CASTGC"
		p:cookiePath="/cas" />

3、修改修改WEB-INF\spring-configuration\warnCookieGenerator.xml,修改p:cookieSecure=”false”

	<bean id="warnCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
		p:cookieSecure="false"
		p:cookieMaxAge="-1"
		p:cookieName="CASPRIVACY"
		p:cookiePath="/cas" />

经过以上三步,cas server端修改完毕

CAS配合server4.0返回用户更多信息

打开deployerConfigContext.xml

<bean id="attributeRepository" class="org.jasig.services.persondir.support.StubPersonAttributeDao"
            p:backingMap-ref="attrRepoBackingMap" />

将以上代码替换成以下代码:

<bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
		<!-- 指定使用的数据源,此处dataSource是已配置好的数据源 -->
		<constructor-arg index="0" ref="dataSource" />
		<!-- 从数据库中查询信息的SQL语句,通常只需要修改表名即可 -->
		<constructor-arg index="1" value="select * fromuserinfo where {0}" />
		<property name="queryAttributeMapping">
			<map>
				<!-- 上述查询的参数,将userName替换为表中表示用户名的字段名称 -->
				<entry key="username" value="userName" />
			</map>
		</property>
		<property name="resultAttributeMapping">
			<map>
				<!-- 需要返回给Web应用的其它信息,多个信息时可继续增加entry节点 -->
				<!--key值为数据表中的字段名称,value值为Client端取值时的名称标识 -->
				<entry key="address" value="address" />
			</map>
		</property>
	</bean>

 

 

接着在这个文件最后的 bean class=”org.jasig.cas.services.RegexRegisteredService” 标签内加上 p:ignoreAttributes=”true”

 

 

CAS Server3.5.2 + Client3.2.1 单点登录(无证书全攻略)

配置环境:
JDK 1.6 + TOMCAT 6
Yale CAS Server3.5.2 + Client3.2.1

工作准备:
到 http://www.jasig.org/cas 中下载对应版本的 服务器端cas-server-3.5.2-release.zip 和 客户端cas-client-3.2.1-release.zip

一、尝试运行CAS服务器端
解压cas-server-3.5.2-release.zip, 在里面的moudles文件夹里有个cas-server-webapp-3.5.2.war文件, 这个就是服务器的所有文件, 解压, 设置tomcat的server.xml把该文件夹添加对应的虚拟目录, 我们以 http://localhost:8080/cas 为例,登录 http://localhost:8080/cas 后你们可以看到登录界面,便于测试,CAS默认输入相同的账号跟密码即可通过登录验证。

二、配置CAS服务端,使其读取mysql数据库对应的数据进行登录判断

打开CAS的/WEB-INF/deployerConfigContext.xml,找到以下代码并注释掉,取消掉原来的用于测试的简单验证

<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />

换成以下的验证方式

<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
	<property name="dataSource" ref="dataSource" />
	<property name="sql" value="SELECT password FROM account WHERE email=?" />
</bean>

并配置对应的数据源(添加bean):

	<!-- 配置数据源 -->
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName">
			<value>com.mysql.jdbc.Driver</value>
		</property>
		<property name="url">
			<value>jdbc:mysql://localhost:3306/sway_account?useUnicode=true&amp;characterEncoding=utf-8</value>
		</property>
		<property name="username">
			<value>root</value>
		</property>
		<property name="password">
			<value></value>
		</property>
	</bean>

 

三、配置CAS客户端

新建一个tomcat虚拟目录,我们以 http://localhost:8080/test 为例,并且确保里面有一个可访问的文件(我们这里以index.jsp为例),解压cas-client-3.2.1-release.zip,在里面modules里面找到cas-client-core-3.2.1.jar以及commons-logging-1.1.jar文件,复制到 http://localhost:8080/test 项目里面的 WEB-INF/lib 文件夹里面,然后修改里面的web.xml文件,添加以下过滤器:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>  
	</welcome-file-list>

	<listener>
		<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
	</listener>

	<!--该过滤器用于实现单点登出功能,可选配置。 -->
	<filter>
		<filter-name>CAS Single Sign Out Filter</filter-name>
		<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>CAS Single Sign Out Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!--该过滤器负责用户的认证工作,必须启用它 -->
	<filter>
		<filter-name>CASFilter</filter-name>
		<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
		<init-param>
			<param-name>casServerLoginUrl</param-name>
			<param-value>http://localhost:8080/cas/login</param-value>
			<!--这里的server是服务端的IP -->
		</init-param>
		<init-param>
			<param-name>serverName</param-name>
			<param-value>http://localhost:8080/</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CASFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- 该过滤器负责对Ticket的校验工作,必须启用它 -->
	<!-- ValidationFilter 这个filter负责对请求参数ticket进行验证(ticket参数是负责子系统与CAS进行验证交互的凭证)casServerUrlPrefix:CAS服务访问地址serverName:当前应用所在的主机名 -->
	<filter>
		<filter-name>CAS Validation Filter</filter-name>
		<filter-class>
			org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter
		</filter-class>
		<init-param>
			<param-name>casServerUrlPrefix</param-name>
			<param-value>http://localhost:8080/cas</param-value>
		</init-param>
		<init-param>
			<param-name>serverName</param-name>
			<param-value>http://localhost:8080/</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CAS Validation Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- 3.(可选)HttpServletRequestWrapperFilter 这个是HttpServletRequet的包裹类,让他支持getUserPrincipal,getRemoteUser方法来取得用户信息 -->
	<!-- 该过滤器负责实现HttpServletRequest请求的包裹,比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登 -->
	<filter>
		<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
		<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- 4.(可选)AssertionThreadLocalFilter 这个类把Assertion信息放在ThreadLocal变量中,这样应用程序不在web层也能够获取到当前登录信息 Assertion assersion =AssertionHolder.getAssertion(); -->
	<!--该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。比如AssertionHolder.getAssertion().getPrincipal().getName()。-->
	<filter>
		<filter-name>CAS Assertion Thread Local Filter</filter-name>
		<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>CAS Assertion Thread Local Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

</web-app>

 

四、读取更多的客户端信息

打开CAS的/WEB-INF/deployerConfigContext.xml,
找到bean id为attributeRepository的这个配置,修改为如下

	
	<bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
		<constructor-arg index="0" ref="dataSource" />
		<constructor-arg index="1">
			<value>select * from account where {0}</value>
		</constructor-arg>
		<!-- 组装sql用的查询条件属性 -->
		<property name="queryAttributeMapping">
			<map>
				<entry key="username" value="email" />
				<!-- <entry key="username" value="userAccount" /> -->
			</map>
		</property>
		<!-- 如果要组装多个查询条件,需要加上下面这个,默认为AND -->
		<!-- <property name="queryType">
			<value>OR</value>
		</property> -->
		<!-- 要获取的属性在这里配置 -->
		<property name="resultAttributeMapping">
			<map>
				<!--key为对应的数据库字段名称,value为提供给客户端获取的属性名字,系统会自动填充值 -->
				<entry key="id" value="id" />
				<entry key="email" value="email" />
				<entry key="emailValidated" value="emailValidated" />
				<entry key="password" value="password" />
				<entry key="registerTime" value="registerTime" />
				<entry key="lastLoginTime" value="lastLoginTime" />
				<entry key="balance" value="balance" />
			</map>
		</property>
	</bean>

修改该xml文件中最后一个默认的serviceRegistryDao bean,找到<bean class=”org.jasig.cas.services.RegexRegisteredService”>把高亮部分添加进去:

<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" />
                        <property name="ignoreAttributes" value="true"/>
                    </bean>

最后修改WEB-INF\view\jsp\protocol\2.0\casServiceValidationSuccess.jsp文件

<%@page pageEncoding="UTF-8"%>
<%@ page session="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>

<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>

	<cas:authenticationSuccess>
        <cas:user>${fn:escapeXml(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.id)}</cas:user>                
        <c:if test="${not empty pgtIou}">
                <cas:proxyGrantingTicket>${pgtIou}</cas:proxyGrantingTicket>
        </c:if>
        <c:if test="${fn:length(assertion.chainedAuthentications) > 1}">
                <cas:proxies>
                <c:forEach var="proxy" items="${assertion.chainedAuthentications}" varStatus="loopStatus" begin="0" end="${fn:length(assertion.chainedAuthentications)-2}" step="1">
                            <cas:proxy>${fn:escapeXml(proxy.principal.id)}</cas:proxy>
                </c:forEach>
                </cas:proxies>
        </c:if>
        <!-- 在server验证成功后,这个页面负责生成与客户端交互的xml信息,在默认的casServiceValidationSuccess.jsp中,只包括用户名,并不提供其他的属性信息,因此需要对页面进行扩展 -->
        <c:if test="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes) > 0}">   
            <cas:attributes>   
                <c:forEach var="attr" items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}">                             
                    <cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}>                                 
                </c:forEach>     
            </cas:attributes>   
        </c:if> 
    </cas:authenticationSuccess>

</cas:serviceResponse>

然后即可使用以下代码在index.jsp中获取对应的返回对象:

AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();
Map<String, Object> attributes = principal.getAttributes();

以下是我用于测试的index.jsp

<%@ page language="java" import="java.util.*" contentType="text/html;charset=utf-8"%>
<%@ page import="org.jasig.cas.client.authentication.AttributePrincipal,org.jasig.cas.client.validation.Assertion,org.jasig.cas.client.util.AbstractCasFilter"%>

<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
	<base href="<%=basePath%>">
	<title>CAS单点登录VS退出</title>
</head>
<body>

<%
AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();
Map<String, Object> attributes = principal.getAttributes();
/*for(Map.Entry<String,Object> m: attributes.entrySet()){ 
	System.out.println(m.getKey()+"---"+m.getValue()); 
}*/
%>

[ 单点登录测试 ]<br /><br />
用户名:<%=principal.getName()%><br />
id:<%=attributes.get("id")%><br />
email:<%=attributes.get("email")%><br />
emailValidated:<%=attributes.get("emailValidated")%><br />
password:<%=attributes.get("password")%><br />
registerTime:<%=attributes.get("registerTime")%><br />
lastLoginTime:<%=attributes.get("lastLoginTime")%><br />
balance:<%=attributes.get("balance")%><br />
<br />
<a href="http://localhost:8080/sway/cas/logout">退出</a><br /><br />
<hr/>
<br /><br />
[ DEBUG ]<br /><br />
map中元素个数为<%=attributes.size()%>

</body>

</html>

至此配置完毕,往后再教大家配置对应的SSL加密。

close