1.今日總結(jié)
今天主要是對(duì)CAS配置數(shù)據(jù)庫連接椎组,獲取數(shù)據(jù)庫屬性。以及如何自定義加密算法進(jìn)行了相關(guān)的調(diào)研宴抚。( 用于CAS系統(tǒng)登錄的密碼默認(rèn)提供MD5和SHA加密的算法支持布轿,但有時(shí)由于業(yè)務(wù)需要,以上兩種算法都不能提供足夠的支持朝聋,這時(shí)我們就需要自定義加密算法嗡午。)
網(wǎng)上對(duì)于CAS-5.X的描述較少,大多集中在4.x的XML配置階段冀痕,對(duì)5.X的描述只有在官網(wǎng)上比較完整荔睹。(官方文檔對(duì)于好多地方?jīng)]有講到,所以只有去嘗試言蛇。)
2.今日問題
在總結(jié)今天遇到的問題前僻他,先要介紹下本人的項(xiàng)目搭建。因?yàn)樵诰W(wǎng)上查找資料時(shí)腊尚,發(fā)現(xiàn)很多不一樣的構(gòu)建方式吨拗。
本人是直接通過git clone https://github.com/apereo/cas-gradle-overlay-template.git
源碼進(jìn)行build。在READ.ME里面有詳細(xì)的介紹婿斥,如何去搭建CAS服務(wù)劝篷。
2.1.問題1
搭建好CAS服務(wù)后,需要整合數(shù)據(jù)庫受扳,然后使用數(shù)據(jù)庫中已有的用戶名和密碼去登錄携龟。配置數(shù)據(jù)庫的時(shí)候兔跌,遇到的第一個(gè)問題是:自己直接從官網(wǎng)上拷貝過來一大堆的配置項(xiàng)勘高,心里想的是,肯定能用到,先跑起來再說华望,果然無法成功蕊蝗,pair看了之后說,你配置了那么多赖舟,你都知道是什么意思嗎蓬戚?
問題1反思
這是一個(gè)做事方式的問題,很嚴(yán)重宾抓,寫代碼不應(yīng)該是靠運(yùn)氣子漩,應(yīng)該清楚的知道每一步是干什么的。有什么作用石洗?所以對(duì)數(shù)據(jù)庫重新進(jìn)行了配置,首先配置項(xiàng)都是寫在properties(當(dāng)然還可以在其他的地方寫幢泼,官網(wǎng)有介紹,有優(yōu)先級(jí)讲衫,會(huì)去不同的地方尋找配置項(xiàng))
cas.authn.jdbc.query[0].sql=select password from users where userName=?//注意和表名要一模一樣缕棵,區(qū)分大小寫
cas.authn.jdbc.query[0].url=jdbc:mysql://mysql:3306/BronzeSword?useUnicode=yes&characterEncoding=UTF-8
cas.authn.jdbc.query[0].user=BronzeSword//用戶名
cas.authn.jdbc.query[0].password=password//密碼
cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver//驅(qū)動(dòng)
注意:這個(gè)是要配置查詢的字段,否則就會(huì)認(rèn)證失敗涉兽,最重要的是官方文檔并沒有說明
cas.authn.jdbc.query[0].fieldPassword=password
總結(jié)招驴。
其實(shí)回頭想想,這個(gè)和spring data jpa等是差不多的配置枷畏,原理上很相同别厘,但是自己在配置時(shí),沒有想到這些拥诡,其實(shí)多想想應(yīng)該是可以想到丹允。
問題2
因?yàn)橹绊?xiàng)目中的用戶密碼在存入數(shù)據(jù)庫時(shí)是經(jīng)過MD5加密的,所以在認(rèn)證時(shí)袋倔,需要進(jìn)行MD5校驗(yàn)雕蔽,這個(gè)官方文檔寫的很清楚,直接配置
cas.authn.jdbc.query[0].passwordEncoder.type=DEFAULT
cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=MD5
cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8
果然用戶輸入密碼時(shí)宾娜,經(jīng)過了一次MD5運(yùn)算批狐。
但是問題來了:默認(rèn)的MD5加密算法一般不能滿足要求,例如在我的項(xiàng)目中其實(shí)是使用了兩次MD5前塔,這就需要我們自己去實(shí)現(xiàn)加密算法嚣艇。
先看官方文檔:
cas.authn.jdbc.query[0].passwordEncoder.type=NONE|DEFAULT|STANDARD|BCRYPT|SCRYPT|PBKDF2|com.example.CustomPasswordEncoder
這里說明了我們可以自己創(chuàng)建自己的passwordEncoder,例如com.example.CustomPasswordEncoder华弓,實(shí)現(xiàn)時(shí)需要繼承PasswordEncoder類食零。好的,我們來實(shí)現(xiàn)這個(gè)接口
import org.springframework.security.authentication.encoding.PasswordEncoder;
public class CustomPasswordEncoder implements PasswordEncoder
繼承之后發(fā)現(xiàn)這個(gè)類已經(jīng)被棄用了寂屏,果然進(jìn)去源碼查看
/** @deprecated */
@Deprecated
public interface PasswordEncoder {
String encodePassword(String var1, Object var2);
boolean isPasswordValid(String var1, String var2, Object var3);
}
在官方文檔上沒有找到對(duì)應(yīng)的說明贰谣,于是進(jìn)行g(shù)oogle:
然后又去看BCrypt,離解決問題越來越遠(yuǎn)娜搂。
問題2反思
其實(shí)這個(gè)問題在于我寫代碼時(shí),沒有仔細(xì)看清楚是實(shí)現(xiàn)哪個(gè)接口吱抚,并且在錯(cuò)誤發(fā)生時(shí)也沒有認(rèn)真的去思考百宇,如果多看一眼就會(huì)發(fā)現(xiàn)
其實(shí)IDEA已經(jīng)提醒了你應(yīng)該使用哪個(gè)類,對(duì)使用沒有被棄用的PasswordEncoder.然后實(shí)現(xiàn)兩個(gè)抽象方法:
@Override
public String encode(CharSequence charSequence) {
return getMD5(getMD5(charSequence.toString()));
}
@Override
public boolean matches(CharSequence charSequence, String s) {
System.out.println("char:" + charSequence.toString());
System.out.println("s:" + s);
return encode(charSequence).equals(s);
}
在這里對(duì)它的設(shè)計(jì)思想不是很明白秘豹,一個(gè)encode去實(shí)現(xiàn)自己的加密邏輯携御,一個(gè)matches方法去對(duì)比結(jié)果,從而判斷認(rèn)證既绕。(一個(gè)方法不行嗎啄刹?)
在這里還有個(gè)問題:
那就是我在創(chuàng)建項(xiàng)目時(shí),一開始時(shí)創(chuàng)建在了根目錄凄贩,就是不能成功鸵膏?最后將該類移動(dòng)到了cas目錄下。
其實(shí)這個(gè)問題(反思)怎炊,自己也可以想到谭企,從gradle管理項(xiàng)目中就可以看到,因?yàn)樵谧钔鈱拥膅radle中包含了一個(gè)subproject,在內(nèi)嵌的subproject中评肆,有spring boot的插件债查,即CAS是運(yùn)行在spring boot之上的,所以說自定義加密算法的代碼肯定是要在CAS中瓜挽,而自己卻又沒想到盹廷?
3.Action
遇到問題,多嘗試久橙,多思考俄占;多嘗試,多思考淆衷。(三遍)