`
xiaoxin5230
  • 浏览: 87753 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

CAS(2)

    博客分类:
  • j2ee
阅读更多

                              Cas整合UcCenter数据库

CASWeb应用系统提供了单点登录服务。它的特性包括:一个开放和具有很好文档支持的协议;一个Java开源服务器组件;提供多种类型的客户端包括Java.NetPHPPerlApacheuPortal等;能够与uPortalBlueSocketTikiWikiMule LiferayMoodle集成使用。

Cas原理和协议:

从结构上来看cas包含两部分:cas server cas Client .casServer需要独立部署,主要负责对用户的认证工作,cas client负责对客户端受保护资源的访问请求。需要登录时,重定向到cas服务器

CAS Client 与受保护的客户端应用部署在一起,以 Filter 方式保护受保护的资源。对于访问受保护资源的每个 Web 请求,CAS Client 会分析该请求的 Http 请求中是否包含 Service Ticket,如果没有,则说明当前用户尚未登录,于是将请求重定向到指定好的 CAS Server 登录地址,并传递 Service (也就是要访问的目的资源地址),以便登录成功过后转回该地址。用户输入认证信息,如果登录成功,CAS Server 随机产生一个相当长度、唯一、不可伪造的 Service Ticket,并缓存以待将来验证,之后系统自动重定向到 Service 所在地址,并为客户端浏览器设置一个 Ticket Granted CookieTGC),CAS Client 在拿到 Service 和新产生的 Ticket 过后,与 CAS Server 进行身份核实,以确保 Service Ticket 的合法性。

在该协议中,所有与 CAS 的交互均采用 SSL 协议,确保,ST TGC 的安全性。协议工作过程中会有 2 次重定向的过程,但是 CAS Client CAS Server 之间进行 Ticket 验证的过程对于用户是透明的。

配置cas server:

1.    下载cas

http://www.jasig.org/cas_server_3_4_2_1

下载最新的cas_server_3_4_2_1.zip 服务器端,解压后找到cas-server-3.4.2.1-release\cas-server-3.4.2.1\modules\cas-server-webapp.war,将这个war进行解压到tomcatwebapps目录下.

将刚才解压出的目录cas-server-webapp进行重命名为cas

启动tomcat 输入http://localhost:8080/cas/login 查看是否成功部署

 

默认的认证方式是用户名和密码相同则认证成功。这个肯定是不能满足项目的需求的,所以需要和用户数据库配置起来

2.配置数据库

首先的将一些包导入进来,这里使用的是dbcp来配置数据库

 

将上述包拷贝到cas\WEB-INF\lib

 cas-server-support-jdbc-3.4.2.1.jar包中,提供了 3 个基于 JDBC  AuthenticationHandler,分别为BindModeSearchDatabaseAuthenticationHandler, QueryDatabaseAuthenticationHandler, SearchModeSearchDatabaseAuthenticationHandler

我们这里使用的是QueryDatabaseAuthenticationHandler,它是通过配置一个 SQL 语句查出密码

打开文件cas/WEB-INF/deployerConfigContext.xml,找到

<bean

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

 

 

将它替换为

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

    <property name="sql" value="select password from uc_members where lower(username)=lower(?)"/>              

       <property name="dataSource">

       <ref local="dataSource"/>

       </property> 

</bean>

                             

 

并在最后加入

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">

                     <property name="driverClassName" value="com.mysql.jdbc.Driver"/>

                     <property name="url" value="jdbc:mysql://localhost:3306/ucenter"/>

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

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

                     <property name="maxActive" value="20"/>

                     <property name="maxIdle" value="20"/>

                     <property name="maxWait" value="20"/>   

      </bean>

                             

重启后输入用户名和密码登陆。这里整合的是discuzdiscuz的密码进行了加密,我们还得附加加密功能。

3.加密
分析:公司使用的是discuz6.1.用户密码使用的是MD5(MD5+salt(重数据库取出的随机数)) 所以现在认证就不能使用QueryDatabaseAuthenticationHandler,从而必须重写CAS的密码校验模块
步骤:1.实现

package org.jasig.cas.authentication.handler.support;

 

 

import java.util.List;

import java.util.Map;

 

import org.jasig.cas.adaptors.jdbc.AbstractJdbcUsernamePasswordAuthenticationHandler; 

import org.jasig.cas.authentication.handler.AuthenticationException; 

import org.jasig.cas.authentication.handler.BadPasswordAuthenticationException; 

import org.jasig.cas.authentication.handler.UnknownUsernameAuthenticationException; 

import org.jasig.cas.authentication.principal.UsernamePasswordCredentials; 

import org.springframework.dao.IncorrectResultSizeDataAccessException; 

import org.springframework.jdbc.core.BeanPropertyRowMapper; 

import org.springframework.jdbc.core.JdbcTemplate; 

import org.springframework.jdbc.support.rowset.SqlRowSet;

 

/**

 * @className:JdbcUsernamePasswordAuthHandlerImpl.java

 * @classDescription:

 * @author:xiayingjie

 * @createTime:2010-8-11

 */

public class JdbcUsernamePasswordAuthHandlerImpl extends AbstractJdbcUsernamePasswordAuthenticationHandler { 

 

              

    // it's better to move below properties to external configure file, for example 'maxFailureTimes' 

    private static final String QUERY_USER_SQL = "select salt,password from uc_members where username = ?"; 

 

 

 

    /**

     * authenticate username password internal

     *

     * @param credentials

     *            credentials

     * @throws AuthenticationException

     *             AuthenticationException

     * @return true if user login success

     * @see org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler

     *      #authenticateUsernamePasswordInternal(rg.jasig.cas.authentication.principal.UsernamePasswordCredentials)

     */ 

    @Override 

    protected boolean authenticateUsernamePasswordInternal(final UsernamePasswordCredentials credentials) 

        throws AuthenticationException { 

        final String username = credentials.getUsername(); 

        final String password = credentials.getPassword(); 

        JdbcTemplate template = new JdbcTemplate(getDataSource()); 

 

        try { 

 

          Map mp= template.queryForMap(QUERY_USER_SQL, new String[]{username});

         

          String salt=(String) mp.get("salt");

          String userPassword=(String) mp.get("password");

 

          String cPassword=MD5.getInstance().createMD5(MD5.getInstance().createMD5(password)+salt);

         

          if(cPassword.equals(userPassword)){

              return true;

          } else{                               

              return false;

          }

 

        } catch (final IncorrectResultSizeDataAccessException e) { 

            // this means the username was not found. 

            throw new UnknownUsernameAuthenticationException(); 

        } 

    } 

 

} 

 

其中里面使用了MD5,这个类是从网上随便找的一个
package org.jasig.cas.authentication.handler.support;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5 {
 private MessageDigest md;
 private static MD5 md5;
 private MD5()
 {
  try {
   md=MessageDigest.getInstance("md5");
  } catch (NoSuchAlgorithmException e) {
   System.out.println("没有这种算法");
  }
 }
 //产生一个MD5实例
 public static MD5 getInstance()
 {
  if(null!=md5)
   return md5;
  else
  {
   makeInstance();
   return md5;
  }
 }
 //保证同一时间只有一个线程在使用MD5加密
 private static synchronized void makeInstance()
 {
  if(null==md5)
   md5=new MD5();
 }
 
 public String createMD5(String pass)
 {
  md.update(pass.getBytes());
  byte[] b=md.digest();
  return byteToHexString(b);
 }
 private String byteToHexString(byte[] b)
 {
  StringBuffer sb=new StringBuffer();
  String temp="";
  for(int i=0;i<b.length;i++)
  {
   temp=Integer.toHexString(b[i]&0Xff);
   if(temp.length()==1)
    temp="0"+temp;
   sb.append(temp);
  }
  return sb.toString();
 }
 public static void main(String[] args) {
  System.out.println(MD5.getInstance().createMD5((MD5.getInstance().createMD5("asdf")+"e61bb7")));
 }
}
 
修改认证方式:
修改cas部署包下的WEB-INF目录下的deployerConfigContext.xml
<property name="authenticationHandlers">
<list>
<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
p:httpClient-ref="httpClient" />
<bean class="org.jasig.cas.authentication.handler.support.JdbcUsernamePasswordAuthHandlerImpl">  
              <property name="dataSource" ref="dataSource" />  
 </bean> 
</list>
</property>
到此cas整合discuz加密已经全部完成。。
5. Tomcat SSL安全验证

如果要实现CAS的单点登入,这是必须的

1.       生产密钥

2.       点击开始’ ’运行,输入cmd

CD  X:\jdk根目录\Java\jdk1.6.0_14\bin

CD X:

 

打开系统的hosts文件,我们定义2个解析

127.0.0.1                   casserver

127.0.0.1                   server1

下文中导入过程密码统一使用password

keytool -genkey -alias cas-server -keyalg RSA -keypass password -storepass password -keystore casserver.keystore

输入密码后,在第一个提示输入姓名(CN)的时候,输入你的CAS服务端域名或者hosts文件里定义的映射,casserver

 

国家(C)输入CN

 

keytool -export -alias cas-server -storepass password -file casserver.cer -keystore  casserver.keystore

 

 

 

 

 

keytool -import -trustcacerts -alias server -file casserver.cer -keystore “jre根目录/lib/security/cacerts “ -storepass changeit  

(keytool -import -trustcacerts -alias server -file casserver.cer -keystore cacerts  -storepass changeit  )

注意,这个 changeit cacerts 文件(密钥库)的密码,不是刚才设置的密钥密码,  changeit 为密钥库的默认密码

如果操作成功,会在jdk bin目录下看到casserver.cer  casserver.keystore 这两个文件

如果项目中已经存在证书 则删除证书

keytool -delete -alias server -keystore "%JAVA_HOME%/jre/lib/security/cacerts" -storepass changeit

keytool -delete -alias server -keystore cacerts -storepass changeit

 

打开tomcat目录下conf/ server.xml 文件,找到

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"

               maxThreads="150" scheme="https" secure="true"

               clientAuth="false" sslProtocol="TLS" />

 

 

 

将注释去掉,修改为

<Connector port="8443" protocol="HTTP/1.1"  SSLEnabled="true"

maxHttpHeaderSize="8192"

maxThreads="150" minSpareThreads="25" maxSpareThreads="75"

enableLookups="false" disableUploadTimeout="true"

acceptCount="100" scheme="https" secure="false"

clientAuth="false" sslProtocol="TLS"

keystoreFile=" casserver.keystore所在的目录\casserver.keystore" keystorePass="password"

         truststoreFile="jre目录/lib/security/cacerts" truststorePass="changeit"

/>

 

 

 

默认的密钥有效期是3个月,可以根据自己需求修改

访问https://casserver:8443/cas/login 测试是否部署成功

 

6. keytool用法

keytool 用法:

-certreq     [-v] [-protected]

             [-alias <别名>] [-sigalg <sigalg>]

             [-file <csr_file>] [-keypass <密钥库口令>]

             [-keystore <密钥库>] [-storepass <存储库口令>]

             [-storetype <存储类型>] [-providername <名称>]

             [-providerclass <提供方类名称> [-providerarg <参数>]]  

             [-providerpath <路径列表>]

-changealias [-v] [-protected] -alias <别名> -destalias <目标别名>

             [-keypass <密钥库口令>]

 

             [-keystore <密钥库>] [-storepass <存储库口令>]

             [-storetype <存储类型>] [-providername <名称>]

             [-providerclass <提供方类名称> [-providerarg <参数>]]

             [-providerpath <路径列表>]

-delete      [-v] [-protected] -alias <别名>

             [-keystore <密钥库>] [-storepass <存储库口令>]

             [-storetype <存储类型>] [-providername <名称>]

             [-providerclass <提供方类名称> [-providerarg <参数>]]

             [-providerpath <路径列表>]

-exportcert  [-v] [-rfc] [-protected]

             [-alias <别名>] [-file <认证文件>]

             [-keystore <密钥库>] [-storepass <存储库口令>]

             [-storetype <存储类型>] [-providername <名称>]

             [-providerclass <提供方类名称> [-providerarg <参数>]]

             [-providerpath <路径列表>]

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics