即時聊天IM之二 openfire 整合現有系統用戶

合肥程序員群:49313181。??? 合肥實名程序員群:128131462 (不愿透露姓名和信息者勿加入)
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群討論有什么問題咨詢的歡迎打擾。商業合作當然更歡迎

?

?

轉載于:https://www.cnblogs.com/egojit/p/4900726.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/375450.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/375450.shtml
英文地址,請注明出處:http://en.pswp.cn/news/375450.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

cannot convert ‘_IO_FILE*’ to ‘const char*

錯誤代碼 #ifdef NDEBUG#define DBUG_PRINT(fmt, ...) #else#define DBUG_PRINT(fmt, ...) printf(fmt, ##__VA_ARGS__) #endifBUG_PRINT(stderr, "decode %s does not support device type cuda.\n", dec->name);修改 BUG_PRINT("decode %s does not supp…

找出數組中前K大的值

將數組劃分為兩部分&#xff0c;前K項為前K大值的集合&#xff0c;無需有序。 while(true) {int flag nums[k];while(i < k && nums[i] > flag) {i;}while(j>k && nums[j] < flag) {j--;}if (i j || nums[i] nums[j]) {break;}int tmp nums[i]…

C#在ASP.NET4.5框架下的首次網頁應用

運行效果預覽: 先看實踐應用要求: 1&#xff0e;編寫一個函數&#xff0c;用于計算1&#xff01;2&#xff01;3&#xff01;4&#xff01;5&#xff01;&#xff0c;在控制臺或頁面輸出運行結果。 2&#xff0e;在控制臺或頁面輸出九九乘法表。 3&#xff0e;輸入10個以內的整…

javascript的變態位運算

javascript的變態位運算 var a "10" | 0; alert(a); alert (typeof a);結果為10,number。 這就是說這條語句可以將字符串轉化為number。 如果&#xff1a;var a "sss" | 0;alert(a);結果為0.parseInt("sss")的話&#xff0c;會返回NaN。這個太…

CUDA: OpenCV requires enabled ‘cudev‘ module from ‘opencv_contrib

wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/4.X.X.zip unzip opencv_contrib.zip cmake -D OPENCV_EXTRA_MODULES_PATH~/opencv_contrib-4.X.X/modules參考

Android-Universal-Image-Loader三大組件DisplayImageOptions、ImageLoader、ImageLoaderConfiguration詳解...

轉 一、介紹 Android-Universal-Image-Loader是 一個開源的UI組件程序&#xff0c;該項目的目的是提供一個可重復使用的儀器為異步圖像加載&#xff0c;緩存和顯示。所以&#xff0c;如果你的程序里需要這個功能的話&#xff0c;那么不妨試試它。 因為已經封裝好了一些類和方法…

營銷類文章 SEO

如何有效的推廣網站 適合沒錢的中小站長 唐世軍 a5總經理 博客 門戶網站廣告報價—以新浪為例 貴的一天30多萬 碧藍天營銷學院 網絡營銷&#xff0c;你真的了解嗎&#xff1f; SEO工具mozBar介紹、友情鏈接新參考mozRank 談談網絡推廣團隊每天工作流程、工作標準、考核 請問安卓…

顯示 grep 結果的指定行

用grep查找特定關鍵字&#xff0c;結果很多&#xff0c;但是有用的在中間的某幾行&#xff0c;即grep得到結果之后再次過濾出指定幾行。 首先查找指定行 grep -a "X" filename | grep -an "X"記下指定行&#xff0c;然后用awk打印指定行 grep -a "…

Java小知識

內部類分為: 成員內部類、靜態嵌套類、方法內部類、匿名內部類。(1)、內部類仍然是一個獨立的類&#xff0c;在編譯之后內部類會被編譯成獨立的.class文件&#xff0c;但是前面冠以外部類的類名和$符號。(2)、內部類不能用普通的方式訪問。成員變量成員變量靜態成員變量。List遍…

C++ 設置線程名字

使用 std::thread #include <thread> #include <pthread.h>std::thread t(funs, args); pthread_setname_np(t.native_handle(), threadName);通過 pthread_create 創建 #define _GNU_SOURCE #include <pthread.h>pthread_t tid; pthread_create(&ti…

java學習_File屬性處理

// TODO Auto-generated method stub File filenew File("newhello.txt"); //文件是否存在 System.out.println("文件是否存在&#xff1a;"file.exists()); //讀取文件名稱 System.out.println("讀取文件名&#xff1a;"file.getName()); //讀取…

pytest 基礎講解

文章目錄 一、前置說明二、操作步驟1. 安裝 pytest2. python 編寫測試用例3. 在 pycharm 中使用 pytest 運行測試用例1)執行單條用例:點擊用例前面的三角形執行,或在用例內部點擊右鍵2)執行多條用例:在測試用例的外部區域,點擊右鍵,批量執行所有用例4. 命令行中使用 pyt…

Myeclipse8.6中安裝SVN插件

方法一&#xff1a; 1.打開HELP->MyEclipse Configuration Center&#xff0c;切換到SoftWare標簽頁。   2.點擊Add Site 打開對話框&#xff0c;在對話框Name輸入Svn&#xff0c;URL中輸入&#xff1a;http://subclipse.tigris.org/update_1.6.x   3.在左邊欄中找到Per…

初識EL

一、EL函數庫介紹 由于在JSP頁面中顯示數據時&#xff0c;經常需要對顯示的字符串進行處理&#xff0c;SUN公司針對于一些常見處理定義了一套EL函數庫供開發者使用。  這些EL函數在JSTL開發包中進行描述&#xff0c;因此在JSP頁面中使用SUN公司的EL函數庫&#xff0c;需要導入…

ffmpeg 合并 flv 文件

// 轉ts char cmd[1024] {\0}; sprintf(cmd, "ffmpeg -i %s -loglevel quiet -c copy -bsf:v h264_mp4toannexb -f mpegts %s", lastFlvFile.c_str(), lastTsFile.c_str()); system(cmd);// 合并ts char cmd[1024] {\0}; sprintf(cmd, "ffmpeg -i concat:\&qu…

怎么樣的理解才是完全理解SQL(二)

如果我們從集合論&#xff08;關系代數&#xff09;的角度來看&#xff0c;一張數據庫的表就是一組數據元的關系&#xff0c;而每個 SQL 語句會改變一種或數種關系&#xff0c;從而產生出新的數據元的關系&#xff08;即產生新的表&#xff09;。我們學到了什么&#xff1f;思考…

Scala學習筆記-環境搭建以及簡單語法

關于環境的搭建&#xff0c;去官網下載JDK8和Scala的IDE就可以了&#xff0c;Scala的IDE是基于Eclipse的。 下面直接上代碼&#xff1a; 這是項目目錄&#xff1a; A是scala寫的&#xff1a; package first import scala.collection.mutable.ListBufferobject A {def main(args…

UVa 12169 (枚舉+擴展歐幾里得) Disgruntled Judge

題意&#xff1a; 給出四個數T, a, b, x1,按公式生成序列 xi (a*xi-1 b) % 10001 (2 ≤ i ≤ 2T) 給出T和奇數項xi&#xff0c;輸出偶數項xi 分析&#xff1a; 最簡單的辦法就是直接枚舉a、b&#xff0c;看看與輸入是否相符。 1 #include <cstdio>2 3 const int maxn …

使用Beautifulsoup爬取藥智網數據

使用Beautifulsoup模塊爬取藥智網數據 Tips&#xff1a;1.爬取多頁時&#xff0c;先用一頁的做測試&#xff0c;要不然ip容易被封 2.自己常用的處理數據的方法&#xff1a; regre.compile(正則表達式) datareg.sub(要替換的字符串,data) 代碼&#xff08;其實沒多少&#xff09…

冪集 返回某集合的所有子集

冪集。編寫一種方法&#xff0c;返回某集合的所有子集。集合中不包含重復的元素。 說明&#xff1a;解集不能包含重復的子集。 示例: 輸入&#xff1a; nums [1,2,3]輸出&#xff1a; [[3],[1],[2],[1,2,3],[1,3],[2,3],[1,2],[] ]來源&#xff1a;力扣&#xff08;LeetCode…