`
wang5598
  • 浏览: 111226 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

CAS单点登陆部署

 
阅读更多

这阵子在研究yale大学的jasig项目下面的CAS单点登陆系统(项目地址是:http://www.jasig.org/cas),经过一周的测试,整个安装部署都已经成功了,现在将部署过程记录如下:

 

一、准备工作:

装好JDK(1.6),Tomcat(6.0),下载CAS服务端和客户端(cas-server-3.4.11-release和cas-client-3.2.1-release,这两个版本是目前最新的,下载地址是:http://www.jasig.org/cas_server_3_4_11_release)。

 

二、设置证书:

生成服务端的证书,这里和其它教程一样采用的都是JDK所自带的keytool工具:

1).生成证书(server端):
keytool -genkey -alias mycas -keyalg RSA -keystore d:\keys\mycas.keystore;
2.导出证书(server端):
keytool -export -trustcacerts -file d:\keys\mycas.crt -alias mycas -keystore d:\keys\mycas.keystore
3.查看证书(client端,即存放子应用的机器,我这里以windows演示):
(首先进入JDK目录 cd C:\Program Files\Java\jdk1.6.0_10\jre\lib\security)  keytool -list -keystore cacerts
4.导入证书(client端,为方便演示,我在client的D盘下也建了这个目录,然后把crt文件放进去了):
keytool -import -trustcacerts -keystore cacerts -file d:\keys\mycas.crt -alias mycas -storepass changeit
 5.删除证书(client端,不是必须的操作,这里只是列出来,需要删除的时候才用的):
keytool -delete -trustcacerts -alias mycas -keystore cacerts -storepass changeit

 

 

 

 

 

三、开启服务端Tomcat的SSL连接服务,确保Tomcat所用的JDK和之前所装的JDK是相同的(有的eclipse中的tomcat是用的eclipse自带的jdk的,这个要区分好的)。

修改Tomcat的conf下面server.xml文件,去掉以下代码的注释,然后添加你自己的keystore.
 <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" 
               maxThreads="150" scheme="https" secure="true" 
               clientAuth="false" sslProtocol="TLS"
               keystoreFile="d:\keys\mycas.keystore"  
               keystorePass="你的密码"
    />

 

四、设置服务端配置文件。首先将cas-server-3.4.11解压后,复制modules下面的cas-server-webapp-3.4.11.war到tomcat的webapp下面(手动解压或者启动tomcat解压)。启动tomcat后,就可以在地址栏,以https://wangyq(我自己的计算机名):8443/cas/ 来进行访问了.



 

cas的配置文件在deployerConfigContext.xml中默认的登陆验证方式是SimpleTestUsernamePasswordAuthenticationHandler,也就是用户名和密码一致就可以登陆;我们通常需要从数据库中取出用户名和密码进行验证,所以我们需要修改deployerConfigContext.xml,配置我们自己的服务认证方式:首先在deployerConfigContext.xml配置我们数据源,在<sec:user-service id="userDetailsService">这个节点后面添加casDataSource:

<bean id="casDataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName">
	<value>oracle.jdbc.driver.OracleDriver</value>
    </property>
    <property name="url">
	<value>jdbc:oracle:thin:@10.0.12.67:1521:orcl</value>
    </property>    
    <property name="username">
	<value>username</value>    
    </property>
    <property name="password">
	<value>yourpassword</value>
    </property>
</bean>

 

然后注释掉SimpleTestUsernamePasswordAuthenticationHandler,添加QueryDatabaseAuthenticationHandler:

<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
   <property name="dataSource" ref="casDataSource" />
   <property name="sql" value="select password from userinformation where username = ?" /> 
</bean>

 说明:默认的它是不带数据库的驱动的,要自己把相应的数据库驱动程序放到cas的lib下面,我这里需要的ojdbc.jar.

 

五、配置客户端, 简单点就是把官方提供的客户端的jar加入到第三方应用的项目中,然后在第三方应用的web.xml中配置好对应的过滤器即可了。我这里把我的cas-client-core-3.2.1.jar这个包直接加入到我的第三方应用的lib下面了,然后在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>

        <!-- 该过滤器负责用户的认证工作,必须启用它;serverName中填写第三方应用所在服务器的连接地址,注意不要出现localhost或者127.0.0.1,不然会出现无法同步登出的问题  -->
        <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>https://wangyq:8443/cas/login</param-value>
                        <!--这里的server是服务端的IP-->
                </init-param>
                <init-param>
                        <param-name>serverName</param-name>
                        <param-value>http://192.168.5.100:8080</param-value>
                </init-param>
        </filter>
        <filter-mapping>
                <filter-name>CASFilter</filter-name>
                <url-pattern>/*</url-pattern>
        </filter-mapping>

        <!-- 该过滤器负责对Ticket的校验工作,必须启用它;serverName中填写第三方应用所在服务器的连接地址,注意不要出现localhost或者127.0.0.1,不然会出现无法同步登出的问题 -->
        <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>https://wangyq:8443/cas</param-value>
                </init-param>
                <init-param>
                        <param-name>serverName</param-name>
                        <param-value>http://192.168.5.100:8080</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>
        
        <!-- 自动根据单点登录的结果设置本系统的用户信息 -->
        <filter>
                <display-name>AutoSetUserAdapterFilter</display-name>
                <filter-name>AutoSetUserAdapterFilter</filter-name>
                <filter-class>cn.util.AutoSetUserAdapterFilter</filter-class>
        </filter>
        <filter-mapping>
                <filter-name>AutoSetUserAdapterFilter</filter-name>
                <url-pattern>/*</url-pattern>
        </filter-mapping>
        <!-- ======================== 单点登录结束 ======================== -->

 然后附上AutoSetUserAdapterFilter这个过滤器的代码:

package cn.util;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.jasig.cas.client.validation.Assertion;
import cn.domain.UserInformation;

/**
 * CAS单点登陆的过滤器功能类,该类用来自动生成子应用的登陆Session
 * 
 */
public class AutoSetUserAdapterFilter  implements Filter {
	
    /**
     * Default constructor. 
     */
    public AutoSetUserAdapterFilter() {
    }

    /**
     * @see Filter#destroy()
     */
    public void destroy() {
    }

   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
                   ServletException {
           HttpServletRequest httpRequest = (HttpServletRequest) request;
           
           // _const_cas_assertion_是CAS中存放登录用户名的session标志
           Object object = httpRequest.getSession().getAttribute("_const_cas_assertion_");
           
           if (object != null) {
                   Assertion assertion = (Assertion) object;
                   String loginName = assertion.getPrincipal().getName();
                   UserInformation user = UserUtil.getCurrentUser(httpRequest);
                   
                   // 第一次登录系统
                   if (user == null) {
                	   user = cn.util.CommomMethod.getUserBean(loginName);
                           // 保存用户信息到Session
                          UserUtil.saveUserToSession(user,httpRequest);
                   }
                   
           }
          	chain.doFilter(request, response);
   }

	   /**
	    * @see Filter#init(FilterConfig)
	    */
	   public void init(FilterConfig fConfig) throws ServletException {
	   }
		
}

 UserUtil就是一个简单的操作用户登录session的一个工具类,代码如下:

package cn.util;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import cn.domain.UserInformation;

/**
 * 该类被用来保存、获取、删除用户的SessionBean信息
 * @author WangYQ
 *
 */
public class UserUtil{
	 /**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
     *      用户的Session标志
     */
    public static String USER = "ui";
    /**
     *      已登录的用户
     */
    public static Map<String, UserInformation> loginUsers = new HashMap<String, UserInformation>();

    /**
     * 保存用户信息到Session
     * @param user
     */
    public static void saveUserToSession(UserInformation user,HttpServletRequest httpRequest) {
    	httpRequest.getSession().setAttribute("ui", user);
    }

    /**
     * 获取当前登录的用户
     * @return
     */
    public static UserInformation getCurrentUser(HttpServletRequest httpRequest) {
    	HttpSession session = httpRequest.getSession();
    	if(session!=null){
    		Object sessionUser  = session.getAttribute("ui");
    		if(sessionUser == null){
    			return null;
    		}
    		UserInformation user =  (UserInformation) sessionUser;
    		return user;
    	}else{
    		return null;
    	}
    }

    /**
     * 获取当前用户的帐号
     * @return 当前用户的帐号
     */
    public static String getCurrentUserName(HttpServletRequest httpRequest) {
    	Object sessionUser = getCurrentUser(httpRequest);
    	if(sessionUser==null){
    		return "";
    	}else{
    		UserInformation user =  (UserInformation) sessionUser;
    		return user.getUsername();
    	}
    }

    /**
     * 从session中移除用户
     */
    public static void removeUserFromSession(HttpServletRequest httpRequest) {
    	httpRequest.getSession().removeAttribute("ui");
    }
}

 

 CommomMethod.getUserBean这也是一个工具类中根据用户帐号获取用户信息bean的一个方法,为了演示我简化下代码:

package cn.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.util.ServletContextAware;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import com.opensymphony.xwork2.ActionContext;
import cn.domain.UserInformation;
import cn.service.SessionService;
import cn.domain.UserInformation;

public class CommomMethod {
	
	private static JdbcTemplate template ;
	//其它的业务代码省略	
	public static UserInformation getUserBean(String username){
		UserInformation UI = new UserInformation();
		int type = 1;
        String uname="",upass="";
        SqlRowSet rs =null;
        template = HibernateSessionFactory.gettemplate();
        String hsql = "select username,password,type,realname,roletype,schoolname,school_id,role_name,avatarurl,isupdate from userinformation where username='"+username+"'";
        rs = template.queryForRowSet(hsql);
        while(rs.next()){
        	uname  = rs.getString(1);
        	upass   =  rs.getString(2);
        	type = rs.getInt(3);
        	UI.setUsername(uname);
        	UI.setPassword(upass);
        	UI.setType(type);
        	UI.setRealname(rs.getString("realname"));
        	UI.setRoletype(rs.getInt("roletype"));
        	UI.setSchoolname(rs.getString("schoolname"));
        	UI.setSchool_id(rs.getInt("school_id"));
        	UI.setRolename(rs.getString("role_name"));
        	UI.setAvatarurl(rs.getString("avatarurl"));
        	UI.setUpdate(rs.getString("isupdate").equals("1"));
        }
		return UI;
	}
}

 UserInformation 就是一个简单的javabean存放的用户的一些基本属性,我这里是直接使用的jdbctemplate,如果你使用的是hibernate的话,可以自行变更获取方法;

 

六、最后一步,就是把由服务端生成的证书导入到第三方应用所在服务器的JDK的受信任的证书列表中,详细的可以看第二步骤中的第四小点,需要说明的是,要在cmd中首先进入到jdk的目录中(cd C:\Program Files\Java\jdk1.6.0_10\jre\lib\security),然后再导入操作。那至此全部操作就已经完成了,导入证书完成后,分别启动服务端cas和客户端的应用,就能实现自己的单点登陆和单点登出了。

 

 总结一点:CAS的单点登陆安装和配置我已经成功完成了,目前对代码的研究还没开始,只是处在一个逻辑流程的熟悉阶段,感觉其实最主要的工作还是在客户端,通过过滤器把所有的对于第三方应用的未登录访问全部指向到cas的server进行验证,验证成功后再把地址redirect到先前的service上面。

 

写这篇文章,参考了很多别人的东西,这里推荐两个教程:

http://www.wsria.com/archives/1349(咖啡兔,写的很详细,我开始也是参照着来做的)

http://wenku.baidu.com/view/a2352819227916888486d7e8.html(百度文库,一些细节写的很详细)

 

最后新年第一天报道,祝大家龙年龙马精神,步步高升,呵呵~

 

  • 大小: 73.6 KB
  • 大小: 15.7 KB
  • 大小: 55.2 KB
  • 大小: 137.1 KB
分享到:
评论
3 楼 焦志广 2013-09-12  
启动tomcat
java.lang.Exception: Connector attribute SSLCertificateFile must be defined when using SSL with APR
at org.apache.tomcat.util.net.AprEndpoint.bind(AprEndpoint.java:507)
at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:610)
at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:429)
at org.apache.catalina.connector.Connector.initInternal(Connector.java:981)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
at org.apache.catalina.core.StandardService.initInternal(StandardService.java:559)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:814)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
at org.apache.catalina.startup.Catalina.load(Catalina.java:640)
at org.apache.catalina.startup.Catalina.load(Catalina.java:665)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:281)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:455)
2 楼 wang5598 2012-05-07  
有没有详细的报错信息? CAS Server的包中本来就没有这个common_rosters.js的呀——!
1 楼 xucaishen 2012-04-26  
3.4.11部署后测试无法登录,而且报common_rosters.js文件不存在错误.
换回3.4.7后成功登录,common_rosters.js文件不存在错误还是有.

相关推荐

    改造CAS单点登录部署文件

    改造CAS单点登录部署文件 博客所需文件 http://blog.csdn.net/zhu_tianwei/article/details/19156949

    基于Java集成CAS单点登录【接部署即可启用】

    基于Java中CAS的单点登录,有服务端的所有源码,将tomcat目录下的所有资源直接拷到Tomcat服务中间件的webapp目录下,阅读tomcat-webapp中的read.txt文档,查看使用说明,适用于第一次开发CAS单点登录的同学们,简单...

    CAS单点登录服务端部署包

    CAS 是 Central Authentication Service 的缩写 —— 中央认证服务,一种独立开放指令协议,是 Yale 大学发起的一个企业级开源项目,旨在为 Web 应用系统提供一种可靠的 SSO 解决方案。 CAS 支持以下特性: CAS v1, ...

    CAS单点登录操作文档

    CAS单点登录操作文档 CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。CAS 具有以下特点: • 开源的企业级单点登录解决...

    CAS整合LDAP实现单点登录原理及部署

    CAS整合LDAP实现单点登录的原理及部署学习笔记,cas实现单点登录,ldap负责账户管理

    cas单点登录需要的jar包

    cas单点登录需要的jar包,在使用以cas为单点登录框架时,需要导入相关的jar包并且配置web.xml来完成部署

    CAS单点登录系统.doc

    CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。CAS 具有以下特点: • 开源的企业级单点登录解决方案。 • CAS Server ...

    使用CAS整合CXF实现单点登录部署步骤

    使用tomcat部署CAS项目 使用CXF整合CAS

    java-cas单点登录服务端

    CAS(Central Authentication Service)是一款不错的针对 Web 应用的单点登录框架,本文介绍了 CAS 的原理、协议、在 Tomcat 中的配置和使用,研究如何采用 CAS 实现轻量级单点登录解决方案。 CAS 是 Yale 大学发起的...

    struts2+spring+cas单点登录

    使用struts2+spring+cas实现的单点登录功能,里面包括cas-server3.5.2项目一个,cas-client3.2.1 web项目两个,数据库脚本,请按照里面的说明文档进行部署,希望你们也能配置成功。

    cas单点登录server端代码

    CAS单点登录,SERVER端代码,内付instruction文件,可以直接将war包部署在服务器上,座位sso的认证server端,具体参看本人博文

    单点登录服务端项目cas-server

    单点登录服务端项目cas-server单点登录服务端项目cas-server 单点登录服务端项目cas-server 单点登录服务端项目cas-server 单点登录服务端项目cas-server 单点登录服务端项目cas-server 单点登录服务端项目cas-...

    cas单点登录系统

    cas单点登录系统,带源码,可定制开发;CASServer负责完成对用户的认证工作,CASServer需要独立部署,CASServer处理用户名/密码等凭证(Credentials)验证,它可能会到数据库检索一条用户帐号信息,也可能在XML文件中...

    CAS单点登陆配置手册

    CAS 是 Yale (耶鲁)大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。CAS 具有以下特点: •开源的企业级单点登录解决方案。 •CAS ...

    cas5.2单点登陆源码

    cas5.2单点登陆源码,比较新的版本,支持springboot跟springcloud部署

    cas实现单点登录服务端及客户端

    cas实现单点登录服务端及客户端,压缩包内提供三个工程,一个cas服务器,两个测试客户端,可同时部署到一个tomcat下,或者分开部署。端口号默认使用的8000

    落雨博客基于CAS框架的单点登录技术讲解(ppt+code实例+doc)配套资料

    3 CAS单点登录简介(针对实践选择的技术) 5 3.1 技术快速使用说明 5 3.1.1 设置服务器域名 5 3.1.2 生成证书(这里采用JDK自带的工具keytool) 5 3.1.3 为客户端JVM导入证书 6 3.1.4 将证书应用到Web服务器Tomcat 7...

    cas单点登陆配置文档

    单点登录的英文名称为Single Sign-On,简写为SSO,它是一个用户认证的过程,允许用户一次性进行认证之后,就访问系统中不同的应用;而不需要访问每个应用时,都重新输入密码。IBM对SSO有一个形象的解释“单点登录、...

    Cas单点登录在服务器下部署

    欢迎下载,请多指教。(*^__^*) 嘻嘻……

    单点登录cas服务端部署war包,已编译,直接部署运行

    war直接放在tomcat下面运行即可,无须任何配置,访问地址http://127.0.0.1:8081/cas/login

Global site tag (gtag.js) - Google Analytics