轉:http://blog.csdn.net/ae6623/article/details/8851801
本篇將講解cas-server端的認證方式
1.最簡單的認證,用戶名和密碼一致就登錄成功
2.配置oracle的jdbc數據源,通過spring動態查詢數據庫
3.配置oracle和mysql的數據源,通過spring動態查詢數據庫,一個滿足就立即登錄成功
4.配置oracle和mysql的數據源,以及添加一個java類,三者認證,有一個滿足就立即登錄成功。
5.穿插自定義的MD5加密類對用戶的密碼進行加密和數據庫里已經MD5加密的密碼做對比。
好的,開始吧。
測試一:
ps:記得添加上所需的jar包,否則控制台會提示找不到數據庫驅動這種低級錯誤。
jar包:
--------------------------------------------
cas-server-support-jdbc-3.3.3.jar
ojdbc14.jar
mysql-connector-java-5.1.16-bin.jar
--------------------------------------------
(1)最簡單的認證,用戶名和密碼一致就登錄成功
步驟:打開你的C:\tomcat7\webapps\casServer\WEB-INF\deployerConfigContext.xml文件
<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
測試二:
(2)配置oracle的jdbc數據源,通過spring動態查詢數據庫
步驟:
1.打開你的C:\tomcat7\webapps\casServer\WEB-INF\deployerConfigContext.xml文件
2.注釋掉那句很白痴的用戶名和密碼一致就讓你認證通過的那行xml代碼
3.添加oracle認證模式,添加自定義的MD5類,添加默認的cas的MD5驗證類,添加oracle的數據源
<span style="font-family:Microsoft YaHei;font-size:14px;"><property name="authenticationHandlers"> <list> <bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" p:httpClient-ref="httpClient" p:requireSecure="false" /> <!-- 不https驗證: p:requireSecure="false" --> <!-- 默認認證模式:用戶名和密碼一致就認證通過 <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" /> --> <!--配置驗證類1--> <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"> <property name="dataSource" ref="dataSource"></property> <property name="sql" value="select pw from sys_acct_auth where user_code =?"></property> <!--下面這個是我自定義的MD5加密類--> <property name="passwordEncoder" ref="RS10Md5PasswordEncoder"></property> <!--下面這個是cas提供的MD5加密類,下面會有bean,你自己一睜眼就看到了,玩過spring的應該看一眼就吐了 <property name="passwordEncoder" ref="MD5PasswordEncoder" ></property> --> </bean> </list> </property> <!-- 增加數據源1--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" /> <property name="url" value="jdbc:oracle:thin:@192.168.168.144:1521:hpora" /> <property name="username" value="muapp10g" /> <property name="password" value="ceshiku" /> </bean> <!--數據驗證模式1 cas默認MD5加密類,返回值:加密后的字符串--> <bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder"> <constructor-arg index="0" value="MD5" /> </bean> <!--數據驗證模式2 我自定義的MD5加密類,返回值:加密后的字符串--> <bean id="RS10Md5PasswordEncoder" class="org.jasig.cas.authentication.handler.Crypt"></bean></span>
測試三:
(3)配置oracle和mysql的數據源,通過spring動態查詢數據庫,一個滿足就立即登錄成功
(4)配置oracle和mysql的數據源,以及添加一個java類,三者認證,有一個滿足就立即登錄成功。
(5)穿插自定義的MD5加密類對用戶的密碼進行加密和數據庫里已經MD5加密的密碼做對比。
有人說我的web1應用和web2應用擁有各自的用戶群,各自的注冊數據庫,怎么辦?對啊怎么辦?
那么我們就在驗證類的List標簽里面多添加幾個驗證類,只要有一個驗證方式通過了,我們就讓用戶登錄成功,如何?
開始干吧,繼續改造上面的那個xml文件。
最終的xml文件如下所示:
<span style="font-family:Microsoft YaHei;font-size:14px;"><property name="authenticationHandlers"> <list> <bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" p:httpClient-ref="httpClient" p:requireSecure="false" /> <!-- 不https驗證: p:requireSecure="false" --> <!-- 默認認證模式:用戶名和密碼一致就認證通過 <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" /> --> <!--配置驗證類1--> <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"> <property name="dataSource" ref="dataSource"></property> <property name="sql" value="select pw from sys_acct_auth where user_code =?"></property> <!--下面這個是我自定義的MD5加密類--> <property name="passwordEncoder" ref="RS10Md5PasswordEncoder"></property> <!--下面這個是cas提供的MD5加密類,下面會有bean,你自己一睜眼就看到了,玩過spring的應該看一眼就吐了 <property name="passwordEncoder" ref="MD5PasswordEncoder" ></property> --> </bean> <!--配置驗證類2--> <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"> <property name="dataSource" ref="dataSourceForMySql"></property> <property name="sql" value="select pw from userInfo where username =?"></property> </bean> <!--配置驗證類3--> <bean class="org.jasig.cas.authentication.handler.RsCasDaoAuthenticationHandler" /> </list> </property> <!-- 增加數據源1--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" /> <property name="url" value="jdbc:oracle:thin:@192.168.168.144:1521:hpora" /> <property name="username" value="muapp10g" /> <property name="password" value="ceshiku" /> </bean> <!-- 增加數據源2--> <bean id="dataSourceForMySql" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"> <value>com.mysql.jdbc.Driver</value> </property> <property name="url"> <value>jdbc:mysql://localhost:3306/userdb</value> </property> <property name="username"> <value>root</value> </property> <property name="password"> <value>123</value> </property> </bean> <!--數據驗證模式1 cas默認MD5加密類,返回值:加密后的字符串--> <bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder"> <constructor-arg index="0" value="MD5" /> </bean> <!--數據驗證模式2 我自定義的MD5加密類,返回值:加密后的字符串--> <bean id="RS10Md5PasswordEncoder" class="org.jasig.cas.authentication.handler.Crypt"></bean></span>
截圖如下:
ok 以上xml文件就可以滿足你的一些簡單的BT需求了。如果看到這里還有什么疑惑的話,我估計就是那些自定義的java類怎么寫了。來來來,我教你。
首先,打開你的myeclipse或者eclipse或者記事本。
先來制作自己的MD5加密類,因為cas它的加密類我測試了,和我自己寫的加密類生成的密碼不一致,所以我才自己制作DIY的MD5加密類,多一個手藝好吃飯嘛,你也別懶,我都做出來了,跟着我一起玩吧。百度上你也找不到教程的。
新建工程,添加jar包:
1.cas-server-core-3.5.2.jar
2.ojdbc14.jar
我們新建一個包:
org.jasig.cas.authentication.handler
在這個包下面新建三個類:
Crypt.java
MD5.java
RsCasDaoAuthenticationHandler.java
這三個類是有講究的,有繼承,有實現,下面做一下詳細的講解
1.Crypt.java這個類,是負責調用MD5工具類,返回加密后的MD5值,必須實現org.jasig.cas.authentication.handler.PasswordEncoder接口
<span style="font-family:Microsoft YaHei;font-size:14px;">/** * Project Name:JhostAddTime * File Name:Crypt.java * Package Name:org.jasig.cas.authentication.handler * Date:2013-4-25下午02:50:55 * Copyright (c) 2013, riambsoft All Rights Reserved. * */ package org.jasig.cas.authentication.handler; /** * ClassName:Crypt <br/> * Function: TODO ADD FUNCTION. <br/> * Reason: TODO ADD REASON. <br/> * Date: 2013-4-25 下午02:50:55 <br/> * @author Administrator * @version * @since JDK 1.5 * @see */ public class Crypt implements PasswordEncoder{ /** * 進行加密編碼 * @param s 要加密的字符串 * @return 加密后的字符串 */ public String encode(String s) { MD5 md5=new MD5(); String ecd=md5.getMD5ofStr(s) ; System.out.println("-------- need =["+ecd+"]") ; return ecd; } }</span>
2.MD5.java
這個類自己寫也可以,從網上直接down也可以,就是一個MD5算法工具類。
<span style="font-family:Microsoft YaHei;font-size:14px;">package com.rsc.rs.pub.util.functions; import java.lang.reflect.*; /************************************************* md5 類實現了RSA Data Security, Inc.在提交給IETF 的RFC1321中的MD5 message-digest 算法。 *************************************************/ public class MD5 { /* 下面這些S11-S44實際上是一個4*4的矩陣,在原始的C實現中是用#define 實現的, 這里把它們實現成為static final是表示了只讀,切能在同一個進程空間內的多個 Instance間共享*/ static final int S11 = 7; static final int S12 = 12; static final int S13 = 17; static final int S14 = 22; static final int S21 = 5; static final int S22 = 9; static final int S23 = 14; static final int S24 = 20; static final int S31 = 4; static final int S32 = 11; static final int S33 = 16; static final int S34 = 23; static final int S41 = 6; static final int S42 = 10; static final int S43 = 15; static final int S44 = 21; static final byte[] PADDING = { -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* 下面的三個成員是MD5計算過程中用到的3個核心數據,在原始的C實現中 被定義到MD5_CTX結構中 */ private long[] state = new long[4]; // state (ABCD) private long[] count = new long[2]; // number of bits, modulo 2^64 (lsb first) private byte[] buffer = new byte[64]; // input buffer /* digestHexStr是MD5的唯一一個公共成員,是最新一次計算結果的 16進制ASCII表示. */ public String digestHexStr; /* digest,是最新一次計算結果的2進制內部表示,表示128bit的MD5值. */ private byte[] digest = new byte[16]; /* getMD5ofStr是類MD5最主要的公共方法,入口參數是你想要進行MD5變換的字符串 返回的是變換完的結果,這個結果是從公共成員digestHexStr取得的. */ public String getMD5ofStr(String inbuf) { md5Init(); md5Update(inbuf.getBytes(), inbuf.length()); md5Final(); digestHexStr = ""; for (int i = 0; i < 16; i++) { digestHexStr += byteHEX(digest[i]); } return digestHexStr; } // 這是MD5這個類的標准構造函數,JavaBean要求有一個public的並且沒有參數的構造函數 public MD5() { md5Init(); return; } /* md5Init是一個初始化函數,初始化核心變量,裝入標准的幻數 */ private void md5Init() { count[0] = 0L; count[1] = 0L; ///* Load magic initialization constants. state[0] = 0x67452301L; state[1] = 0xefcdab89L; state[2] = 0x98badcfeL; state[3] = 0x10325476L; return; } /* F, G, H ,I 是4個基本的MD5函數,在原始的MD5的C實現中,由於它們是 簡單的位運算,可能出於效率的考慮把它們實現成了宏,在java中,我們把它們 實現成了private方法,名字保持了原來C中的。 */ private long F(long x, long y, long z) { return (x & y) | ((~x) & z); } private long G(long x, long y, long z) { return (x & z) | (y & (~z)); } private long H(long x, long y, long z) { return x ^ y ^ z; } private long I(long x, long y, long z) { return y ^ (x | (~z)); } /* FF,GG,HH和II將調用F,G,H,I進行近一步變換 FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent recomputation. */ private long FF(long a, long b, long c, long d, long x, long s, long ac) { a += F (b, c, d) + x + ac; a = ((int) a << s) | ((int) a >>> (32 - s)); a += b; return a; } private long GG(long a, long b, long c, long d, long x, long s, long ac) { a += G (b, c, d) + x + ac; a = ((int) a << s) | ((int) a >>> (32 - s)); a += b; return a; } private long HH(long a, long b, long c, long d, long x, long s, long ac) { a += H (b, c, d) + x + ac; a = ((int) a << s) | ((int) a >>> (32 - s)); a += b; return a; } private long II(long a, long b, long c, long d, long x, long s, long ac) { a += I (b, c, d) + x + ac; a = ((int) a << s) | ((int) a >>> (32 - s)); a += b; return a; } /* md5Update是MD5的主計算過程,inbuf是要變換的字節串,inputlen是長度,這個 函數由getMD5ofStr調用,調用之前需要調用md5init,因此把它設計成private的 */ private void md5Update(byte[] inbuf, int inputLen) { int i, index, partLen; byte[] block = new byte[64]; index = (int)(count[0] >>> 3) & 0x3F; // /* Update number of bits */ if ((count[0] += (inputLen << 3)) < (inputLen << 3)) count[1]++; count[1] += (inputLen >>> 29); partLen = 64 - index; // Transform as many times as possible. if (inputLen >= partLen) { md5Memcpy(buffer, inbuf, index, 0, partLen); md5Transform(buffer); for (i = partLen; i + 63 < inputLen; i += 64) { md5Memcpy(block, inbuf, 0, i, 64); md5Transform (block); } index = 0; } else i = 0; ///* Buffer remaining input */ md5Memcpy(buffer, inbuf, index, i, inputLen - i); } /* md5Final整理和填寫輸出結果 */ private void md5Final () { byte[] bits = new byte[8]; int index, padLen; ///* Save number of bits */ Encode (bits, count, 8); ///* Pad out to 56 mod 64. index = (int)(count[0] >>> 3) & 0x3f; padLen = (index < 56) ? (56 - index) : (120 - index); md5Update (PADDING, padLen); ///* Append length (before padding) */ md5Update(bits, 8); ///* Store state in digest */ Encode (digest, state, 16); } /* md5Memcpy是一個內部使用的byte數組的塊拷貝函數,從input的inpos開始把len長度的 字節拷貝到output的outpos位置開始 */ private void md5Memcpy (byte[] output, byte[] input, int outpos, int inpos, int len) { int i; for (i = 0; i < len; i++) output[outpos + i] = input[inpos + i]; } /* md5Transform是MD5核心變換程序,有md5Update調用,block是分塊的原始字節 */ private void md5Transform (byte block[]) { long a = state[0], b = state[1], c = state[2], d = state[3]; long[] x = new long[16]; Decode (x, block, 64); /* Round 1 */ a = FF (a, b, c, d, x[0], S11, 0xd76aa478L); /* 1 */ d = FF (d, a, b, c, x[1], S12, 0xe8c7b756L); /* 2 */ c = FF (c, d, a, b, x[2], S13, 0x242070dbL); /* 3 */ b = FF (b, c, d, a, x[3], S14, 0xc1bdceeeL); /* 4 */ a = FF (a, b, c, d, x[4], S11, 0xf57c0fafL); /* 5 */ d = FF (d, a, b, c, x[5], S12, 0x4787c62aL); /* 6 */ c = FF (c, d, a, b, x[6], S13, 0xa8304613L); /* 7 */ b = FF (b, c, d, a, x[7], S14, 0xfd469501L); /* 8 */ a = FF (a, b, c, d, x[8], S11, 0x698098d8L); /* 9 */ d = FF (d, a, b, c, x[9], S12, 0x8b44f7afL); /* 10 */ c = FF (c, d, a, b, x[10], S13, 0xffff5bb1L); /* 11 */ b = FF (b, c, d, a, x[11], S14, 0x895cd7beL); /* 12 */ a = FF (a, b, c, d, x[12], S11, 0x6b901122L); /* 13 */ d = FF (d, a, b, c, x[13], S12, 0xfd987193L); /* 14 */ c = FF (c, d, a, b, x[14], S13, 0xa679438eL); /* 15 */ b = FF (b, c, d, a, x[15], S14, 0x49b40821L); /* 16 */ /* Round 2 */ a = GG (a, b, c, d, x[1], S21, 0xf61e2562L); /* 17 */ d = GG (d, a, b, c, x[6], S22, 0xc040b340L); /* 18 */ c = GG (c, d, a, b, x[11], S23, 0x265e5a51L); /* 19 */ b = GG (b, c, d, a, x[0], S24, 0xe9b6c7aaL); /* 20 */ a = GG (a, b, c, d, x[5], S21, 0xd62f105dL); /* 21 */ d = GG (d, a, b, c, x[10], S22, 0x2441453L); /* 22 */ c = GG (c, d, a, b, x[15], S23, 0xd8a1e681L); /* 23 */ b = GG (b, c, d, a, x[4], S24, 0xe7d3fbc8L); /* 24 */ a = GG (a, b, c, d, x[9], S21, 0x21e1cde6L); /* 25 */ d = GG (d, a, b, c, x[14], S22, 0xc33707d6L); /* 26 */ c = GG (c, d, a, b, x[3], S23, 0xf4d50d87L); /* 27 */ b = GG (b, c, d, a, x[8], S24, 0x455a14edL); /* 28 */ a = GG (a, b, c, d, x[13], S21, 0xa9e3e905L); /* 29 */ d = GG (d, a, b, c, x[2], S22, 0xfcefa3f8L); /* 30 */ c = GG (c, d, a, b, x[7], S23, 0x676f02d9L); /* 31 */ b = GG (b, c, d, a, x[12], S24, 0x8d2a4c8aL); /* 32 */ /* Round 3 */ a = HH (a, b, c, d, x[5], S31, 0xfffa3942L); /* 33 */ d = HH (d, a, b, c, x[8], S32, 0x8771f681L); /* 34 */ c = HH (c, d, a, b, x[11], S33, 0x6d9d6122L); /* 35 */ b = HH (b, c, d, a, x[14], S34, 0xfde5380cL); /* 36 */ a = HH (a, b, c, d, x[1], S31, 0xa4beea44L); /* 37 */ d = HH (d, a, b, c, x[4], S32, 0x4bdecfa9L); /* 38 */ c = HH (c, d, a, b, x[7], S33, 0xf6bb4b60L); /* 39 */ b = HH (b, c, d, a, x[10], S34, 0xbebfbc70L); /* 40 */ a = HH (a, b, c, d, x[13], S31, 0x289b7ec6L); /* 41 */ d = HH (d, a, b, c, x[0], S32, 0xeaa127faL); /* 42 */ c = HH (c, d, a, b, x[3], S33, 0xd4ef3085L); /* 43 */ b = HH (b, c, d, a, x[6], S34, 0x4881d05L); /* 44 */ a = HH (a, b, c, d, x[9], S31, 0xd9d4d039L); /* 45 */ d = HH (d, a, b, c, x[12], S32, 0xe6db99e5L); /* 46 */ c = HH (c, d, a, b, x[15], S33, 0x1fa27cf8L); /* 47 */ b = HH (b, c, d, a, x[2], S34, 0xc4ac5665L); /* 48 */ /* Round 4 */ a = II (a, b, c, d, x[0], S41, 0xf4292244L); /* 49 */ d = II (d, a, b, c, x[7], S42, 0x432aff97L); /* 50 */ c = II (c, d, a, b, x[14], S43, 0xab9423a7L); /* 51 */ b = II (b, c, d, a, x[5], S44, 0xfc93a039L); /* 52 */ a = II (a, b, c, d, x[12], S41, 0x655b59c3L); /* 53 */ d = II (d, a, b, c, x[3], S42, 0x8f0ccc92L); /* 54 */ c = II (c, d, a, b, x[10], S43, 0xffeff47dL); /* 55 */ b = II (b, c, d, a, x[1], S44, 0x85845dd1L); /* 56 */ a = II (a, b, c, d, x[8], S41, 0x6fa87e4fL); /* 57 */ d = II (d, a, b, c, x[15], S42, 0xfe2ce6e0L); /* 58 */ c = II (c, d, a, b, x[6], S43, 0xa3014314L); /* 59 */ b = II (b, c, d, a, x[13], S44, 0x4e0811a1L); /* 60 */ a = II (a, b, c, d, x[4], S41, 0xf7537e82L); /* 61 */ d = II (d, a, b, c, x[11], S42, 0xbd3af235L); /* 62 */ c = II (c, d, a, b, x[2], S43, 0x2ad7d2bbL); /* 63 */ b = II (b, c, d, a, x[9], S44, 0xeb86d391L); /* 64 */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; } /*Encode把long數組按順序拆成byte數組,因為java的long類型是64bit的, 只拆低32bit,以適應原始C實現的用途 */ private void Encode (byte[] output, long[] input, int len) { int i, j; for (i = 0, j = 0; j < len; i++, j += 4) { output[j] = (byte)(input[i] & 0xffL); output[j + 1] = (byte)((input[i] >>> 8) & 0xffL); output[j + 2] = (byte)((input[i] >>> 16) & 0xffL); output[j + 3] = (byte)((input[i] >>> 24) & 0xffL); } } /*Decode把byte數組按順序合成成long數組,因為java的long類型是64bit的, 只合成低32bit,高32bit清零,以適應原始C實現的用途 */ private void Decode (long[] output, byte[] input, int len) { int i, j; for (i = 0, j = 0; j < len; i++, j += 4) output[i] = b2iu(input[j]) | (b2iu(input[j + 1]) << 8) | (b2iu(input[j + 2]) << 16) | (b2iu(input[j + 3]) << 24); return; } /* b2iu是我寫的一個把byte按照不考慮正負號的原則的"升位"程序,因為java沒有unsigned運算 */ public static long b2iu(byte b) { return b < 0 ? b & 0x7F + 128 : b; } /*byteHEX(),用來把一個byte類型的數轉換成十六進制的ASCII表示, 因為java中的byte的toString無法實現這一點,我們又沒有C語言中的 sprintf(outbuf,"%02X",ib) */ public static String byteHEX(byte ib) { char[] Digit = { '0','1','2','3','4','5','6','7','8','9', 'A','B','C','D','E','F' }; char [] ob = new char[2]; ob[0] = Digit[(ib >>> 4) & 0X0F]; ob[1] = Digit[ib & 0X0F]; String s = new String(ob); return s; } public static void main(String args[]) { MD5 m = new MD5(); if (Array.getLength(args) == 0) { //如果沒有參數,執行標准的Test Suite System.out.println("MD5 Test suite:"); System.out.println("MD5(\"\"):"+m.getMD5ofStr("")); System.out.println("MD5(\"a\"):"+m.getMD5ofStr("a")); System.out.println("MD5(\"abc\"):"+m.getMD5ofStr("abc")); System.out.println("MD5(\"message digest\"):"+m.getMD5ofStr("message digest")); System.out.println("MD5(\"abcdefghijklmnopqrstuvwxyz\"):"+ m.getMD5ofStr("abcdefghijklmnopqrstuvwxyz")); System.out.println("MD5(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\"):"+ m.getMD5ofStr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")); } else System.out.println("MD5(" + args[0] + ")=" + m.getMD5ofStr(args[0])); } }</span>
3.RsCasDaoAuthenticationHandler.java這個類是我們自定義的認證方式登錄驗證類,你把它當成一開始那個最白痴的用戶名和密碼一致就可以讓用戶認證通過的驗證方式一樣,這樣理解之后,只需要在xml里面配置好了,就能發揮作用了。
它 必須 繼承org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler.java這個類,否則也沒用啊。
這個java類的用途我說一下,它可以干你想干的任何事情,包括去文本文件中提取用戶名和密碼或者連接mysql或者oracle或者其他的之類的事情,總之很方便和實用。(讀取文本神馬的自己寫邏輯去實現)里面的sql語句自己改啊~~
<span style="font-family:Microsoft YaHei;font-size:14px;">/** * Project Name:JhostAddTime * File Name:RsCasDaoAuthenticationHandler.java * Package Name:org.jasig.cas.authentication.handler * Date:2013-4-25下午04:20:35 * Copyright (c) 2013, riambsoft All Rights Reserved. * */ package org.jasig.cas.authentication.handler; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler; import org.jasig.cas.authentication.principal.UsernamePasswordCredentials; /** * ClassName:RsCasDaoAuthenticationHandler <br/> Function: TODO ADD FUNCTION. <br/> Reason: TODO ADD REASON. <br/> Date: 2013-4-25 下午04:20:35 <br/> * * @author Administrator * @version * @since JDK 1.5 * @see */ public final class RsCasDaoAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler { // 構造方法 public RsCasDaoAuthenticationHandler() { } @Override protected boolean authenticateUsernamePasswordInternal(UsernamePasswordCredentials credentials) throws AuthenticationException { // 標志位 Boolean bool = false; String username = credentials.getUsername(); String password = credentials.getPassword(); // 取得MD5加密后的字符串 password = new Crypt().encode(password); System.out.println("開始CAS認證方式 RsCasDaoAuthenticationHandler......"); System.out.println("userName:" + username); System.out.println("password:" + password); // 連接數據庫 Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; String user = "muapp10g"; String pwd = "ceshiku"; String url = "jdbc:oracle:thin:@192.168.168.144:1521:HPORA"; try { try { Class.forName("oracle.jdbc.driver.OracleDriver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } conn = DriverManager.getConnection(url, user, pwd); String sql = "select count(*) from sys_acct_auth where user_code='" + username + "' and pw='" + password + "'"; ps = conn.prepareStatement(sql); rs = ps.executeQuery(); if (rs != null && rs.next()) { int i = rs.getInt(1); if (i > 0) { // 只要有對應的一條記錄通過,就返回true bool = true; } } } catch (SQLException sql) { sql.printStackTrace(); } finally { try { if (rs != null) { rs.close(); } if (ps != null) { ps.close(); } if (conn != null) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } return bool; } }</span>
自定義的這三個類的用法:將此3個文件的class文件拿出來,放到你的Tomcat所在路徑下的指定路徑里,沒有文件夾就自己按照包的路徑新建文件夾即可。
路徑:C:\tomcat7\webapps\casServer\WEB-INF\classes\org\jasig\cas\authentication\handler
截圖:
OK 至此,我們已經搞完了各種驗證方式,我還在研究增加驗證碼模式認證,下一節我們將講解自定義登錄頁面和cas-server端的源碼等內容,歡迎持續關注。
總結:多種認證方式的引入,能夠讓你的用戶群體不用在乎自己是在哪一個數據庫上,無論是A在oracle還是B在mysql還是C是在文本文件,二進制十六進制文件里,只要上述三種認證方式你學會了,那么用戶認證策略很隨意了。
程序端配置:如果自己沒有oracle和mysql請注銷掉C:\tomcat7\webapps\casServer\WEB-INF\deployerConfigContext.xml中的相關配置,否則會報mysql數據源找不到或者oracle加載錯誤的報告。這個源碼一定要配合我的文章,否則你無法運行。