Jasig cas 单点登录系统Server&Java Client配置

Jasig cas(Central Authentication Service)官方站点:http://www.jasig.org/cas,访问这个站点需要。

cas官网文档访问地址:https://wiki.jasig.org/display/CASUM/Home。

我下载的是:3.5.2版本。我配置好的cas界面如下:

界面一:

Jasig cas 单点登录系统Server&Java Client配置_第1张图片

界面二:

Jasig cas 单点登录系统Server&Java Client配置_第2张图片


下载链接:


已经搞好的Java客户端及服务器端(MySQL)配置下载:http://pan.baidu.com/s/11MRPr ,两个war包,1个jar包:

cas.war,是配置好的cas服务器端:http://192.168.1.10:8080/casclient 。

casclient.war,是cas客户端示例,所谓cas客户端,就是指使用cas进行单点登录的系统:  http://192.168.1.10:8080/cas/login。

cas-client-core-3.2.1-SNAPSHOT.jar:是我在版本3.2.1源码基础上进行修改过的,目的是登录成功后,自动跳转到前一页。

要修改cas.war包中deployerConfigContext.xml里面的数据库连接串及密码查询SQL,jasig日志文件的位置:tomcat所在磁盘:/data/applogs/jasig/目录下,可以通过修改WEB-INFO/class/log4j.xml进行配置。

需要的MySQL数据库privilege建表及数据初始化脚本:create_privilege.sql

使用这个数据库,默认的登录帐户密码:root/root


最新代码Git地址:

cas -server-3.5.2:https://github.com/pumadong/cas-server-3.5.2

cas-client-3.2.1:https://github.com/pumadong/cas-client-3.2.1


Jasig cas服务器端配置:


Jasig cas的功能是认证(单点登录,SSO,Single Sign On),关于系统的授权,由于各个系统可能都不太一样,各个系统自行负责为宜。

Jasig cas的配置非常简单,从官网下载的源码包中,有个module目录,里面有制作好的war包,可以直接使用,当然也可以自行使用maven打包,命令如下:

mvn clean package -Dmaven.test.skip=true -U

把war包改名为cas.war,放到tomcat的webapps目录下,就可以使用了,默认使用的是登陆验证类是测试用的,只要用户名、密码一直就算登陆成功,为了在生产环境使用,我们改为使用MySql数据库验证,步骤如下:


1、简单起见,我们不使用https认证,做如下更改:

WEB-INF\spring-configuration目录下ticketGrantingTicketCookieGenerator.xml和warnCookieGenerator.xml,把p:cookieSecure="true"改为p:cookieSecure="false"

WEB-INF目录下deployerConfigContext.xml中,在如下节点中,增加p:requireSecure="false",



2、使用MySql验证

WEB-INF\deployerConfigContext.xml文件中,
节点,做如下更改:
   
   p:httpClient-ref="httpClient" p:requireSecure="false" />

   
   
   
 
   


根节点,也就是beans节点中,增加如下节点:


    
        com.mysql.jdbc.Driver
    

    
        jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
    

    root
    root


    

注意:

同时,需要把cas-server-support-jdbc-3.5.2.jar包放在cas.wab包的WEB-INF目录下,把mysql-connector-java-5.1.24-bin.jar放入Tomcat的WEB-INF/lib目录里。


3、退出时跳转到service页

修改src\main\webapp\WEB-INF\cas-servlet.xml里的logoutController
增加p:followServiceRedirects="true"使支持logout输入service参数为跳转路径。


4、增加免登陆(Remember Me)功能

CAS增加免登陆(Remember Me)功能:

https://wiki.jasig.org/display/CASUM/Remember+Me

http://blog.163.com/wunan_23/blog/static/19556232020111127714418/


Jasig cas客户端配置


1、pom.xml配置



org.jasig.cas
cas-client-core
3.1.10
 

如果不使用maven的话,直接下载jar包即可。


2、web.xml配置




 
      org.jasig.cas.client.session.SingleSignOutHttpSessionListener   
 
 
CAS Single Sign Out Filter   
   org.jasig.cas.client.session.SingleSignOutFilter   
 
 
   CAS Single Sign Out Filter   
   /*   
 
 
   CAS Authentication Filter   
   org.jasig.cas.client.authentication.AuthenticationFilter   
     
       casServerLoginUrl   
       http://localhost:8080/cas/login   
   
 
     
       serverName   
       http://localhost:8080   
   

 
 
   CAS Authentication Filter  
   /*  
 
 
   CAS Validation Filter   
   org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter   
     
       casServerUrlPrefix   
       http://localhost:8080/cas   
   
 
     
       serverName   
       http://localhost:8080   
   

 
 
   CAS Validation Filter   
   /*   


 
CAS Assertion Thread Local Filter
org.jasig.cas.client.util.AssertionThreadLocalFilter


   CAS Assertion Thread Local Filter
   /*



3、单点退出

单点退出的原理,可以总结为一句话:

A客户端退出,调用cas服务器的logout,cas server会向所有相关的接入CAS的系统发送消息,这些接入CAS的系统监听到消息后,触发session失效。

注意:我们的接入CAS的系统必须是cas服务器可以访问到的,如果我们使用:http://localhost:8080/picture的形式访问站点,则是无法实现单点登出的,因为cas服务器访问不到我们的localhost,必须改成:http://ip地址:8080/picture的形式,让CAS可以访问到我们的系统。

参考:

http://www.blogjava.net/xmatthew/archive/2008/07/09/213808.html

http://blog.csdn.net/yuwenruli/article/details/6607669


更改单点登录界面


WEB-INF\view\jsp\default\ui

登陆界面:casLoginView.jsp

登陆成功:casGenericSuccess.jsp

登出界面:casLogoutView.jsp

cas是支持国际化的,关于页面中显示的提示信息的存储位置class/*.properties,默认是en,为了让比较简单的中文化,我把en做了个备份,然后把zh_CN拷贝成en。

在properties文件中, 对于非英文的字符,采用16进制存储,关于unicode字符和16进制字符的转换,提供如下两个函数:

    //把中文字符串转换为十六进制Unicode编码字符串
    public static String stringToUnicode(String s) {
        String str = "";
        for (int i = 0; i < s.length(); i++) {
            int ch = (int) s.charAt(i);
            if (ch > 255)
                str += "\\u" + Integer.toHexString(ch);
            else
                str += "\\" + Integer.toHexString(ch);
        }
        return str;
    }

    //把十六进制Unicode编码字符串转换为中文字符串
    public static String unicodeToString(String str) {
        Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");   
        Matcher matcher = pattern.matcher(str);
        char ch;
        while (matcher.find()) {
            ch = (char) Integer.parseInt(matcher.group(2), 16);
            str = str.replace(matcher.group(1), ch + "");   
        }
        return str;
    }

也可以更改cas-servlet.xml文件中关于本地化的配置,把:

 修改为:

 

这个本地化解析器返回一个固定的本地化信息。默认值为当前JVM的locale。

另外,我在修改一个CAS界面时,运行过程中每次刷新页面都报一个警告:WARN:oejh.HttpGenerator:Ignoring extra content,并且点击页面的submit按钮,大于在第3或者第5次的时候,页面就reload了,后来用排除法(逐渐缩小代码范围)找出问题,我的新界面的login_soft.css中,有关于图片的css:background: url(../../img/bg-white-lock.png) repeat; 但是对应的目录下没有相应图片,导致了如上的两个问题。把图片都拷贝到相应目录后,问题解决。为什么会这样,原因尚不明,估计与CAS的WebFlow相关代码有关,不深入继续研究了


关于log4j.xml


logger的默认additivity值是true,代表日志继续抛出到root进行处理,此时会被root里面所有appender处理;
logger设置additivity的值为false,代表日志被此节点的appender吃掉,不继续抛出;
root里面的只对空的logger节点才生效,比如:


关于源码


服务器端源码(版本:cas-server-3.5.2),实际上我们没有必要对服务器端源码做更改,需要的配置直接修改xml就可以了:

inspektrThrottledSubmissionContext.xml中:应该是spring-beans-3.1.xsd,不能是spring-beans.xsd,否则ref="local"会报错:
cvc-complex-type.3.2.2: Attribute 'local' is not allowed to appear in element 'ref'.

cas-server-webapp项目里面,测试下面的很多xml都是格式不正确(其实可以直接在Eclipse里面把Validate关掉),报如下错误:
The markup in the document following the root element must be well-formed.

avax.servlet.jsp.PageContext cannot be resolved to a type,错误,参考:
http://stackoverflow.com/questions/8669387/javax-servlet-jsp-pagecontext-cannot-be-resolved-to-a-type

以上错误不影响源码编译。

注意,因为我们计划用MySQL进行验证,需要引入JDBC,所以在cas-server-webapp项目的pom.xml中,增加依赖,如下:
   
       org.jasig.cas
       cas-server-support-jdbc
       ${project.version}
 
 

客户端源码(版本:cas-client-3.2.1),修改其中的cas-client-core:
//修改类:org.jasig.cas.client.util.AbstractCasFilter的constructServiceUrl,修改后内容如下:
//return CommonUtils.constructServiceUrl(request, response, this.service, this.serverName, this.artifactParameterName, this.encodeServiceUrl); 
String currentPage = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() 
    + request.getRequestURI()
    + (CommonUtils.isNotBlank(request.getQueryString()) ? ("?"+request.getQueryString()) : "");
String ticket = request.getParameter("ticket");
//http://192.168.1.200:8080/cas/serviceValidate?ticket=ST-74-bJsAKJivCfkABMWLgViu-cas01.example.org&service=http%3A%2F%2Flocalhost%3A8080%2Fauthority%2Fcontroller%2Fmain.do%3Fticket%3DST-74-bJsAKJivCfkABMWLgViu-cas01.example.org
//去掉参数中所有ticket相关的部分
currentPage = currentPage.replace("%3Fticket%3D"+ticket, "");
currentPage = currentPage.replace("&ticket="+ticket, "");
currentPage = currentPage.replace("?ticket="+ticket, "");
currentPage = currentPage.replace("&service=", "?service");
return currentPage;
//或者修改类:org.jasig.cas.client.util.CommonUtils的constructServiceUrl,修改后被替换后的内容如下:
if (CommonUtils.isBlank(serverName)) {
    buffer.append(request.getRequestURL());
}else{
    if (!serverName.startsWith("https://") && !serverName.startsWith("http://")) {
	buffer.append(request.isSecure() ? "https://" : "http://");
    }else{
	buffer.append(serverName);
    }
    buffer.append(request.getRequestURI());
}
目的是,让客户端登陆后,自动跳转到认证前的页面,这样,我们就不需要配置cas.service.url(认证成功的返回页面)参数了,也更合理。

工作原理


如果session有效,则认证通过;
如果session无效,一般是别的系统单点登录,本系统第一次访问,则ticket认证,并session生成;
如果单点退出, 调用cas server的logout,则cas server对所有相关单点发送session失效消息,单点监听此消息并触发session过期;
可以看到,绝大多数认证都是通过session进行的,所以对于后台系统来说,不会有任何性能问题。


参考文章:

http://www.docin.com/p-370942269.html

http://blog.sina.com.cn/s/blog_56d8ea900100l44r.html

http://www.doc88.com/p-183734738161.html

http://wenku.baidu.com/view/5c64b1f19e31433239689318.html

http://www.blogjava.net/tufanshu/archive/2011/01/21/343290.html

http://blog.csdn.net/rishengcsdn/article/details/10379321  (oracle)

你可能感兴趣的:(架构运维)