Liferay门户与CAS实现SSO单点登录

来源:互联网 发布:网络命令 编辑:程序博客网 时间:2024/06/14 04:45

 http://blog.csdn.net/yang_19790212/article/details/6635778

 

1.1 准备工作

1.1.1  安装JDK1.6.0.20

JAVA 1.6.0以上的其他版本也可以,下载安装即可。具体在这里不做描述。

1.1.2  下载TOMCAT6.0.20

TOMCAT6.0以上的其他版本均可,下载解压即可。

1.1.3  下载cas-server-3.4.3.1-release

建议版本号最好一致,否则遇到问题比较难解决。下载好了先放在一边。

1.1.4  下载cas-client-3.1.12-release

建议版本号最好一致,否则遇到问题比较难解决。下载好了先放在一边。

1.2 开始部署

1.2.1  创建证书

1、  创建前先在E盘创建keys目录;

2、  执行命令:

            keytool -genkey -alias mbaobao -keyalg RSA -keystore e:/keys/mbaobao

接下来按下图说明完成:(密码为:mbaobao)

3、  配置本地的虚拟域名

打开hosts用户“记事本”编辑,即notepad

最后加入: 127.0.0.1   sso.mbaobao.com,保存完成。

4、  导出证书,执行命令

keytool -export -file e:/keys/mbaobao.crt -alias mbaobao -keystore e:/keys/mbaobao

输入密码:mbaobao,完成认证的生成

5、为客户端的JVM生成认证,执行以下命令:

keytool -import -keystore e:\keys\cacerts -file e:/keys/mbaobao.crt -alias mbaobao

如下图:(密码:mbaobao)

拷贝E:\keys\ cacerts文件到客户端的JDK相关目录下:

如:D:\Program Files\Java\jdk1.6.0_20\jre\lib\security

 

到这里证书已完成创建。

1.2.2  Tomcat部署CASServer

1、  解压cas-server-3.4.3.1-release.zip包

2、  拷贝cas-server-3.4.3.1\modules\cas-server-webapp-3.4.3.1.war到tomcat\webapps目录下,并改成cas.war名字

3、  如果JAVA_HOME还没有配置好的话,去配置一下,如果配置完成的话,则不用配置了,直接启动tomcat

4、  启动后,停止tomcat,然后看到有一个cas目录,有的话把cas.war删除掉。

5、  配置tomcat/conf/server.xml的第82行左右,放开注释改成如下内容

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="e:/keys/mbaobao" keystorePass="mbaobao" />

注意证书的路径和密码。

6、  启动Tomcat服务,在IE输入https://sso.mbaobao.com:8443/cas,如下图:

点击“继续浏览网站(不推荐)”,如下图:

输入admin/admin登录,如果进入如下图说明配置成功!恭喜你!!!

 

与tomcat相关的配置已经完成。为什么输入admin都可以进去呢?试一下随便弄一个用户名输进去,密码与用户名一样看看效果?是不是也进去了?如果是继续往下看casserver配置。

1.2.3  CASServer配置

1、  注释掉用户名和密码可以进去的功能

打开webapps\cas\WEB-INF\deployerConfigContext.xml文件,注释用”<!--  -->”

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

2、  与后台的mysql关联

在刚才注释的那个位置下面输入:

<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">

<property name="dataSource" ref="dataSource"/>

<property name="sql" value=" SELECT password_ FROM User_ U where emailAddress=? "/>

<property name="passwordEncoder" ref="MD5PasswordEncoder"/>

</bean>

本例是与liferay的user_表相关联,这样的话用户可以统一在liferay的user_表里面,如果后期有需要的话再改成与ldap相关联。

在本xml里面倒数第二行,即</beans>前面加入如下的代码:主要是配置连接方式和采用MD5加密。

<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://192.168.0.81:3306/portal</value></property>

         <property name="username"><value>portal</value></property>

         <property name="password"><value>123456</value></property>

</bean>

<bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">

         <constructor-arg index="0">

             <value>MD5</value>

         </constructor-arg>

</bean>

 

1.2.4  支持中文配置

1、修改web.xml

<filter>

        <description>EncodingFilter</description>

        <filter-name>EncodingFilter</filter-name>

        <filter-class>com.mbb.sso.filter.EncodingFilter</filter-class>

        <init-param>

            <description>encoding_charset</description>

            <param-name>encoding</param-name>

            <param-value>UTF-8</param-value>

        </init-param>

        <init-param>

            <description>ignore?</description>

            <param-name>ignore</param-name>

            <param-value>true</param-value>

        </init-param>

         </filter>

         <filter-mapping>

                            <filter-name>EncodingFilter</filter-name>

                            <url-pattern>/*</url-pattern>

         </filter-mapping>

2、编写过滤器类

package com.mbb.sso.filter;

 

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;

 

public class EncodingFilter implements Filter{

         protected String encoding = null;

    protected FilterConfig filterConfig = null;

    protected boolean ignore = true;

  

    public void destroy() {      

        this.encoding = null;

        this.filterConfig = null;

      

    }

  

    public void doFilter(ServletRequest request, ServletResponse response,

            FilterChain chain)

            throws IOException, ServletException {

      

// Conditionally select and set the character encoding to be used

        if (ignore || (request.getCharacterEncoding() == null)) {

            String encoding = selectEncoding(request);

            if (encoding != null)

                request.setCharacterEncoding(encoding);

        }

      

// Pass control on to the next filter

        chain.doFilter(request, response);

      

    }

  

    public void init(FilterConfig filterConfig) throws ServletException {

      

        this.filterConfig = filterConfig;

        this.encoding = filterConfig.getInitParameter("encoding");

        String value = filterConfig.getInitParameter("ignore");

        if (value == null)

            this.ignore = true;

        else if (value.equalsIgnoreCase("true"))

            this.ignore = true;

        else if (value.equalsIgnoreCase("yes"))

            this.ignore = true;

        else

            this.ignore = false;

      

    }

  

    protected String selectEncoding(ServletRequest request) {

      

        return (this.encoding);

      

    }

}

3、配置tomcat

在connector处增加   URIEncoding="UTF-8"

4、重启一下tomcat

试一下中文用户名登录。

1.2.5  Liferay配置

1、  拷贝证书到e:\keys\ cacerts文件到liferay的jre目录下:

…\liferay-portal-6.0.5\tomcat-6.0.26\jre1.6.0_21\win\lib\security,替换即可

2、  在portal-ext.properties增加下面两行:

passwords.encryption.algorithm=MD5

passwords.digest.encoding=hex

表示md5加密。

3、  启动Liferay,打开liferay 控制面板—> 设置—认证 出现如下界面:

这个“按电子邮件”认证

4、  进入”CAS”界面,如下图:

按图上的进行修改,其中服务器名称是填入liferay的服务器名称。

5、  保存退出

6、  点一下右上角的注销,重新进入liferay系统

7、  点一下右上角的登录,然后就进入了cas的统一登录界面了,输入用户名和密码是不是就进入了liferay系统了?

8、  如果跟平常一样进入了,那就恭喜你!配置成功了!

1.2.6  CASClient配置

1、  JAVA的WEB系统配置

首先先建一个web项目,然后在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>CASFilter</filter-name>       <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>                 

       <init-param>                         

           <param-name>casServerLoginUrl</param-name>                         

           <param-value>https://sso.mbaobao.com:8443/cas/login</param-value>                         

           <!--这里的server是服务端的IP-->                 

       </init-param>                 

       <init-param>                         

           <param-name>serverName</param-name>                         

           <param-value>http://localhost:8088</param-value>                 

       </init-param>         

    </filter>         

    <filter-mapping>                 

       <filter-name>CASFilter</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>https://sso.mbaobao.com:8443/cas</param-value>                 

       </init-param>                 

       <init-param>                         

           <param-name>serverName</param-name>                         

           <param-value>http://localhost:8088</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>com.wsria.demo.filter.AutoSetUserAdapterFilter</filter-class>         

    </filter>         

    <filter-mapping>                 

       <filter-name>AutoSetUserAdapterFilter</filter-name>                  

       <url-pattern>/*</url-pattern>         

    </filter-mapping>  

     -->      

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

其次,导入casclient的jar包,如下图:

最后,编写一个jsp页面测试一下

<%@ page language="java" import="java.util.*,org.jasig.cas.client.authentication.*"pageEncoding="UTF-8"%>

<%

    AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal();  

    String username = principal.getName();

    System.out.println("*****************"+username);

%>

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

      

    <title>My JSP 'index.jsp' starting page</title>

    <meta http-equiv="pragma" content="no-cache">

    <meta http-equiv="cache-control" content="no-cache">

    <meta http-equiv="expires" content="0">   

    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

    <meta http-equiv="description" content="This is my page">

    <!--

    <link rel="stylesheet" type="text/css" href="styles.css">

    -->

  </head>

 

  <body>   

    用户名:<%=username%>

    <a id="logout" href="https://sso.mbaobao.com:8443/cas/logout">退出登录</a></c:if>

  </body>

</html>

测试一下是不是得到用户名了,如果得到的话则说明统一认证通过。

 

1.3 改造界面

主要改造以下几个界面就可以了:

登录界面:casLoginView.jsp
登录成功:casGenericSuccess.jsp
登出界面:casLogoutView.jsp

 

==============

http://my.oschina.net/liferay/blog/5805

Liferay中使用CAS实现单点登陆(SSO)(转载)

2人收藏此文章,收藏此文章 发表于1年前 , 已有1641次阅读 共1个评论2人收藏此文章

点登陆(SSO)的实现方式有很多种,这里所说的是用CAS实现,这也是Liferay中所采纳的方式。至于什么是CAS,单点登陆实现的原理等,这里不做解释,直接一步一步明说实现方式,好了,多一个字的费话也不说了。

第一步,创建证书

keytool -genkey -alias tomcat -keystore c:\mykeystore  -dname "CN=xyb, OU=localhost, O=localhost, L=SH, ST=SH, C=CN" -keypass 123456 -storepass 123456

PS:

 -genkey         创建一个证书
-alias          证书的别名
-keystore       指定生成此证书的路径(可不写,默认存在系统的Home目录下.keystore文件中
-storepass      指定密钥库的密码
-keypass        指定别名条目的密码
-dname          指定证书拥有者信息(可不写,但,系统会提示你依次输入这些信息,特别要注意“CN”的值是你想做为CAS服务器的这台机器的域名或机器名,但就是不能是IP)
-keyalg         指定密钥的算法(可不写)   
-validity       指定创建的证书有效期多少天(可不写,默认为90天)

第二步,导出证书

keytool -export -alias tomcat -keystore c:\mykeystore -file c:\mycerts.cer -storepass 123456

PS:

-export         将别名指定的证书导出到文件
-keystore       指定生成此证书的路径(上一步中写的什么这就写什么,如果没写,这也不写)
 -file           指定导出到文件的文件名

第三步,把导出的证书导入到客户端服务器

keytool -import -trustcacerts -alias tomcat -keystore "%JAVA_HOME%/JRE/LIB/SECURITY/CACERTS" -storepass 123456 -file c:\mycerts.cer

PS:

-import         将已签名数字证书导入密钥库
-file           指定要导入到密钥库的文件名(也就是上一步导出的那个文件)
有一个提示:是否信任这个证书,输入 Y,回车。

第四步,下载cas集成包。将下载后的文件改名为cas-web,放置在liferay的webapps目录下,在conf/server.xml中找到下面这段,去掉原有的注释并修改为:

<Connector port="8443" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" disableUploadTimeout="true" acceptCount="100" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" URIEncoding="UTF-8"  keystorePass="123456" keyAlias="tomcat"/>

第五步,在Liferay的webapps\ROOT\WEB-INF\classes\portal-ext.properties下添加如下内容:

cas.auth.enabled=true
cas.login.url=https://xyb:8443/cas-web/login
cas.logout.url=https://xyb:8443/cas-web/logout
cas.server.name=客户端IP:8080
cas.service.url=
#cas.service.url=http://localhost:8080/c/portal/login
cas.validate.url=https://xyb:8443/cas-web/proxyValidate

如果没在Liferay下,只是普通的Web程序可用Filter来实现

<filter>
        
<filter-name>CASFilter</filter-name>
        
<filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
        
<init-param>
            
<param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
            
<param-value>https://xyb:8443/cas-web/login</param-value>
        
</init-param><!--这里的xyb是CAS服务端的IP或机器名-->
        
<init-param>
            
<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
            
<param-value>https://xyb:8443/cas-web/proxyValidate</param-value>
        
</init-param>
        
<init-param>
          
<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
          
<param-value>localhost:8080</param-value><!--client:port就是需要CAS需要拦截的地址和端口,一般就是这个TOMCAT所启动的IP和port-->
        
</init-param>
    
</filter>
    
    
<filter-mapping>
        
<filter-name>CASFilter</filter-name>
        
<url-pattern>/*</url-pattern><!--这里就是你要拦截的URL请求-->
    
</filter-mapping>

 

最后一步,在客户端获取CAS认证通过的用户名

1、在JSP或Servlet中的用法:

<%@ page import="edu.yale.its.tp.cas.client.filter.CASFilter" %>
<%@ page import="javax.servlet.http.HttpServletRequest" %>
<%@ page import="javax.servlet.http.HttpSession" %>
<%
HttpSession ses 
= request.getSession();

String screenName 
=
(String)ses.getAttribute(CASFilter.CAS_FILTER_USER);
System.out.println(
"screenName==:"+screenName);
%> 

2、在Java中通过 Session 获取登录用户名

// 以下两者都可以
session.getAttribute(CASFilter.CAS_FILTER_USER);
session.getAttribute(
"edu.yale.its.tp.cas.client.filter.user");

3、在 JSTL 中获取用户名的方法

<c:out value="${sessionScope[CAS:'edu.yale.its.tp.cas.client.filter.user']}"/>


问题汇总:

 严重: edu.yale.its.tp.cas.client.CASAuthenticationException: Unable to validate ProxyTicketValidator [[edu.yale.its.tp.cas.client.ProxyTicketValidator prox
yList=[null] [edu.yale.its.tp.cas.client.ServiceTicketValidator casValidateUrl=[https://192.168.1.111:8443/cas/proxyValidate] ticket=[ST-0-9h7Mx5HK3pfsdxRv
MD3y] service=[http%3A%2F%2F192.168.1.222%3A8080%2Fservlets-examples%2Fservlet%2FHelloWorldExample] renew=false]]]

这个CAS异常是从CAS Client里面抛出,是当我们不使用证书的CN去访问域名的时候(比如下文是用IP访问而且证书的CN是该IP对应的域名而非该IP),CASClient无法信任,也就是我上面特意提到的那个CN的问题。要特别注意。

 

INFO [org.jasig.cas.authentication.AuthenticationManager
Impl] - <AuthenticationHandler: cn.com.tiansky.cas.authenticationHandlers.UPAuthenticationHandler successfully authenticated the user which provided the followi
ng credentials: [username: test]>

就种错误,可能是客户端的那个配置文件里写的不太对。也就是上面说的第五步,要多注意一下。

 

java.io.IOException: Cannot recover key
        at org.apache.tomcat.util.net.jsse.JSSE14SocketFactory.init(JSSE14Socket
Factory.java:125)
        at org.apache.tomcat.util.net.jsse.JSSESocketFactory.createSocket(JSSESo
cketFactory.java:88)
        at org.apache.tomcat.util.net.PoolTcpEndpoint.initEndpoint(PoolTcpEndpoi
nt.java:292)
        at org.apache.coyote.http11.Http11BaseProtocol.init(Http11BaseProtocol.j
ava:138)
        at org.apache.catalina.connector.Connector.initialize(Connector.java:101

这种错误,可能是你生成的证书有问题,如果keypass和storepass的密码不一致也会把这个错(不知为什么非要设成一样的)