Q? Q:408365330???? E-Mail:egojit@qq.com
?綜述:
每天利用中午時間更新下這個知識點的的博客如果感興趣的覺得更新慢了也別介意(其它時間還是以工作為主,學習工作兩不誤,哈哈……)。上一篇我純理論上簡單講解了一下XMPP協議,然而現在用的比較多的XMPP協議服務器當然是openfire最為流行(我感覺)。至于如何搭建oprenfire 二次開發環境并且將代碼跑起來,這一篇不介紹了,后面下一篇介紹,也許會有點順序亂的感覺,但是主要還是我最近兩天再搞IM整合現有系統用戶。所以這一遍是記錄篇也是發出來和大家一起分享心得(畢竟網上很多博客是沒有經過驗證的理論篇),我這里都是經過實際環境并且通過測試的,否則我不會記錄。在這里我們需要兩份源代碼,因為在配置中我們會進行源碼調試,一方面我們要讀openfire源碼,另一方面我們要一個客戶端登錄XMPP服務器聊天驗證,首先上著兩份源碼在eclipse中的結構(后面會記錄如何搭建源碼環境并且將源碼跑起來)
圖1
首先Openfire 的源碼使用的是最新的3.10.2版本,客戶端Spark 是pc客戶端,使用的是最新的2.7.2版本,如上圖所示。
首先描述一下業務場景,公司有一個現有的OA系統,是.NET(C#語言)平臺下開發的,使用SqlServer數據庫。讓后給OA加上即時聊天功能,本來是打算維護兩份用戶數據,后來了解到現有OA的用戶是密碼是MD5加密,而openfire默認是Blowfish加密,這個時候如果是新建用戶還好,但是以前在使用的OA系統中MD5加密的用戶怎么辦??如果直接導入到IM用戶表中肯定是無法使用的,這個時候就需要整合現有用戶表,openfire中的用戶表廢棄,只使用現有系統中的用戶表,OA系統和openfire都是通過OA系統用戶表登錄,所以需要整合。然后就免不了分析openfire源碼,才有了下面的文字,根據openfire源碼讓你知其然知其所以然。否則只知道這樣配置,而不知道為什么這樣配置,那就不好了,凡事弄明明白白(程序猿精神)。
openfire整合現有系統用戶
首先明確我的現有系統是一個SqlServer數據庫,IM也是sqlserver(當然混合數據庫也是可以的,已經這樣做過IM是mysql,就有系統是SqlServer)。
一.配置provider.auth.className
?
private static void initProvider() {// Convert XML based provider setup to Database basedJiveGlobals.migrateProperty("provider.auth.className");String className = JiveGlobals.getProperty("provider.auth.className","org.jivesoftware.openfire.auth.DefaultAuthProvider");// Check if we need to reset the auth provider class if (authProvider == null || !className.equals(authProvider.getClass().getName())) {try {Class c = ClassUtils.forName(className);authProvider = (AuthProvider)c.newInstance();}catch (Exception e) {Log.error("Error loading auth provider: " + className, e);authProvider = new DefaultAuthProvider();}}}
由openfire源碼中AuthFactory類我們知道它的靜態函數中調用了這個initProvider()這個靜態函數初始化了一些配置,然后通過這個配置構造了一個AuthProvider。這個配置的鍵為provider.auth.className,默認使用的是org.jivesoftware.openfire.auth.DefaultAuthProvider類,如果我們配置provider.auth.className那么就使用配置的類,然后我們就可以在
openfire源碼中找DefaultAuthProvider類 繼承自JDBCAuthProvider,繼承自AuthProvider類完全符合要求,在數據庫中修改ofProperty表相應的值,如下圖:
圖2
這樣用戶驗證就是通過org.jivesoftware.openfire.auth.JDBCAuthProvider來進行行驗證了。我們繼續跟蹤openfire的java源碼,進入JDBCAuthProvider類,它的構造函數代碼如下:
圖3
由圖3很容易知道,我們要配置各種參數如下:
驅動: jdbcProvider.driver
連接字符串:jdbcProvider.connectionString
查詢密碼的SQL語句:jdbcAuthProvider.passwordSQL
密碼的加密類型:jdbcAuthProvider.passwordType
設置密碼的SQL語句:jdbcAuthProvider.setPasswordSQL
是否允許修改密碼(由后面的源碼知道true或者false):allowUpdate?
那么我們現在來一個一個跟蹤源碼講解整合用戶。
1.配置驅動jdbcProvider.driver ?這里是SQL server數據庫所以用?net.sourceforge.jtds.jdbc.Driver。
2.配置連接字符串jdbcProvider.connectionString ?為:?jdbc:jtds:sqlserver://192.168.11.21:1433/OA_frame;appName=jive;user=sa;password=mm ?替換成你自己的
3.配置查詢密碼字符串jdbcAuthProvider.passwordSQL 為:?select UserPwd from BT_User where UserName=? ?這里的 UserName是用戶登錄名稱,UserPwd就是密碼字段,BT_User就是用戶表。為什么是這樣請看下面源代碼就懂了:
?
圖5?
?4.配置密碼加密類型jdbcAuthProvider.passwordType ? 為md5 ?,但是一定要注意要小些字符串"md5"如果問為什么,那是因為openfire源碼中不認識"MD5"這種大寫。這個支持哪些加密方式呢??很容易有下面的枚舉知道:plain不加密,md5,sha1,sha256,sha512這些加密方式
1 public enum PasswordType { 2 3 /** 4 * The password is stored as plain text. 5 */ 6 plain, 7 8 /** 9 * The password is stored as a hex-encoded MD5 hash. 10 */ 11 md5, 12 13 /** 14 * The password is stored as a hex-encoded SHA-1 hash. 15 */ 16 sha1, 17 18 /** 19 * The password is stored as a hex-encoded SHA-256 hash. 20 */ 21 sha256, 22 23 /** 24 * The password is stored as a hex-encoded SHA-512 hash. 25 */ 26 sha512; 27 }
5. 設置 修改密碼SQL腳本jdbcAuthProvider.setPasswordSQL ?根據自己的需要設置修改密碼腳本,根據源碼可以知道它也是把用戶登錄名作為條件查詢修改的,也就是修改制定登錄名用 戶的密碼。
6. 配置是否允許修改密碼allowUpdate ? ?如果配置了jdbcAuthProvider.setPasswordSQL 就插入true吧。否則jdbcAuthProvider.setPasswordSQL 配置的就沒有用了,看代碼為什么
圖6
通過圖6制定為什么了吧??:)
?
二.配置provider.user.className
?我們配置provider.user.className為?org.jivesoftware.openfire.user.JDBCUserProvider 請看上面圖2。這個配置好了,那么我們就要配置相關屬性了。看下圖代碼:
?圖7
?很容易看出在這里我們要配置哪些屬性:
1.jdbcProvider.driver(上面已經配置)
2.jdbcProvider.connectionString(上面已經配置)
3.jdbcUserProvider.loadUserSQL
4.jdbcUserProvider.userCountSQL
5.jdbcUserProvider.allUsersSQL
6.jdbcUserProvider.searchSQL
7.jdbcUserProvider.usernameField
8.jdbcUserProvider.nameField
9.jdbcUserProvider.emailField
1.配置加載用戶信息SQL腳本jdbcUserProvider.loadUserSQL ?是根據登錄名查詢用戶信息的字符串?select RealName,Email from BT_User where UserName=? 我們再看看源碼:
?圖8
?由上面圖8知道,我們查詢只需要查詢出用戶名(不是登錄名),郵箱就行了,其它的查詢出來也沒什么用,而且字段順序要正確哦(看源碼知道用戶第一次被加載后就放入了緩存)。
2.配置查詢用戶數量腳本jdbcUserProvider.userCountSQL 為:select count(*) from ?BT_User ? 這個就沒什么好說明的了
3.配置用戶登錄名字段?jdbcUserProvider.usernameField ?我們這里就是UserName了
4.配置用戶名jdbcUserProvider.nameField 為:RealName ?這里是昵稱或者是真實姓名,這個就看你具體業務了因為這個是要展示給用戶看到的
5.配置郵箱字段jdbcUserProvider.emailField 為:Email 就是用戶郵箱沒什么可說的
結束:
?上面圍繞配置JDBCAuthProvider和JDBCUserProvider 到這里就完成了,重啟openfire然后這個時候重新登錄用戶發現現在所用的用戶就是舊有系統中的用戶了,用戶整合完成(至少也只是用戶數據整合完成)。更多的配置:如果你系統中有用戶部門什么的,還有如果你希望openfire支持整合后用戶有更多操作那么還需要配置其它東西,我就不一個個說明,但是遵循這種源碼跟蹤思路足夠應付各種配置,已經配置中出現的問題。
綜合配置點:
一):provider.auth.className
驅動: jdbcProvider.driver
連接字符串:jdbcProvider.connectionString
查詢密碼的SQL語句:jdbcAuthProvider.passwordSQL
密碼的加密類型:jdbcAuthProvider.passwordType
設置密碼的SQL語句:jdbcAuthProvider.setPasswordSQL
是否允許修改密碼(由后面的源碼知道true或者false):allowUpdate?
二):provider.auth.className
jdbcProvider.driver(上面已經配置)
jdbcProvider.connectionString(上面已經配置)
jdbcUserProvider.loadUserSQL
jdbcUserProvider.userCountSQL
jdbcUserProvider.allUsersSQL
jdbcUserProvider.searchSQL
jdbcUserProvider.usernameField
jdbcUserProvider.nameField
jdbcUserProvider.emailField
后記:
有興趣或者有問題的可以加上面的QQ群討論有什么問題咨詢的歡迎打擾。商業合作當然更歡迎
?
?