Token簽名與實現(xiàn)

  • 1.對于敏感的api接口,需使用https協(xié)議

https是在http超文本傳輸協(xié)議加入SSL層跨嘉,它在網(wǎng)絡(luò)間通信是加密的川慌,所以需要加密證書

  • 2.簽名的設(shè)計

原理: 用戶登錄后向服務(wù)器提供用戶認證信息(如賬戶和密碼),服務(wù)器認證完后給客戶端返回一個Token令牌,用戶再次獲取信息時梦重,帶上此令牌兑燥,如果令牌正取,則返回數(shù)據(jù)琴拧。對于獲取Token信息后降瞳,訪問用戶相關(guān)接口,客戶端請求的url需要帶上如下參數(shù):
時間戳: timestamp
Token令牌: token
然后將所有用戶請求的參數(shù)按照字母排序(包括timestamp蚓胸,token)挣饥,然后更具MD5加密(可以加點鹽),全部大寫沛膳,生成sign簽名扔枫,這就是 所說的url簽名算法。然后登陸后每次調(diào)用用戶信息時锹安,帶上sign茧吊,timestamp,token參數(shù)

加上時間戳和token:https://www.andy.cn/api/user/update/info.shtml?city=北京×tamp=12445323134&token=wefkfjdskfjewfjkjfdfnc

最終的請求如:https://www.andy.cn /api/user/update/info.shtml?city=北京×tamp=12445323134& token=wefkfjdskfjewfjkjfdfnc&sign=FDK2434JKJFD334FDF2
其最終的原理是減小明文的暴露次數(shù)八毯;保證數(shù)據(jù)安全的訪問

具體實現(xiàn)如下:
1>api請求客戶端向服務(wù)器端一次發(fā)送用用戶認證信息(用戶名和密碼)搓侄,服務(wù)器端請求到改請求后,驗證用戶信息是否正確
如果正確:則返回一個唯一不重復(fù)的字符串(一般為UUID)话速,然后在Redis(任意緩存服務(wù)器)中維護Token----Uid的用戶信息關(guān)系讶踪,以便其他api對token的校驗。
2>服務(wù)器設(shè)計一個url請求攔截規(guī)則
(1) 判斷是否包含timestamp泊交,token乳讥,sign參數(shù),如果不含有返回錯誤碼廓俭。
(2)判斷服務(wù)器接到請求的時間和參數(shù)中的時間戳是否相差很長一段時間(時間自定義如半個小時)云石,如果超過則說明該 url已經(jīng)過期(如果url被盜,他改變了時間戳研乒,但是會導(dǎo)致sign簽名不相等)汹忠。
(3)判斷token是否有效,根據(jù)請求過來的token雹熬,查詢redis緩存中的uid宽菜,如果獲取不到這說明該token已過期。
(4)根據(jù)用戶請求的url參數(shù)竿报,服務(wù)器端按照同樣的規(guī)則生成sign簽名铅乡,對比簽名看是否相等,相等則放行烈菌。(自然url簽名 也無法100%保證其安全阵幸,也可以通過公鑰AES對數(shù)據(jù)和url加密花履,但這樣如果無法確保公鑰丟失,所以簽名只是很大程 度上保證安全)挚赊。
(5)此url攔截只需對獲取身份認證的url放行(如登陸url)臭挽,剩余所有的url都需攔截
3.Token和Uid關(guān)系維護
對于用戶登錄我們需要創(chuàng)建token--uid的關(guān)系,用戶退出時需要需刪除token--uid的關(guān)系

簽名實現(xiàn):
1.獲取全部請求參數(shù)

String sign = request.getParameter("sign");
        Enumeration<?> pNames =  request.getParameterNames();
        Map<String, Object> params = new HashMap<String, Object>();
        while (pNames.hasMoreElements()) {
            String pName = (String) pNames.nextElement();
            if("sign".equals(pName))continue;
            Object pValue = request.getParameter(pName);
            params.put(pName, pValue);
        }

2.生成簽名

public static String createSign(Map<String, String> params, boolean encode)
            throws UnsupportedEncodingException {
        Set<String> keysSet = params.keySet();
        Object[] keys = keysSet.toArray();
        Arrays.sort(keys);
        StringBuffer temp = new StringBuffer();
        boolean first = true;
        for (Object key : keys) {
            if (first) {
                first = false;
            } else {
                temp.append("&");
            }
            temp.append(key).append("=");
            Object value = params.get(key);
            String valueString = "";
            if (null != value) {
                valueString = String.valueOf(value);
            }
            if (encode) {
                temp.append(URLEncoder.encode(valueString, "UTF-8"));
            } else {
                temp.append(valueString);
            }
        }

        return MD5Utils.getMD5(temp.toString()).toUpperCase();
    }
  • SpringSecurity + JWT 實現(xiàn)單點登陸

1.什么是單點登陸
單點登錄(Single Sign On)咬腕,簡稱為 SSO欢峰,是目前比較流行的企業(yè)業(yè)務(wù)整合的解決方案之一。SSO的定義是在多個應(yīng)用系統(tǒng)中涨共,用戶只需要登錄一次就可以訪問所有相互信任的應(yīng)用系統(tǒng)

2.簡單的運行機制
單點登錄的機制其實是比較簡單的纽帖,用一個現(xiàn)實中的例子做比較。某公園內(nèi)部有許多獨立的景點举反,游客可以在各個景點門口單獨買票懊直。
對于需要游玩所有的景點的游客,這種買票方式很不方便火鼻,需要在每個景點門口排隊買票室囊,錢包拿 進拿出的,容易丟失魁索,很不安全融撞。
于是絕大多數(shù)游客選擇在大門口買一張通票(也叫套票),就可以玩遍所有的景點而不需要重新再買票粗蔚。他們只需要在每個景點門 口出示一下剛才買的套票就能夠被允許進入每個獨立的景點尝偎。
單點登錄的機制也一樣,如下圖所示鹏控,

image.png

用戶認證:這一環(huán)節(jié)主要是用戶向認證服務(wù)器發(fā)起認證請求致扯,認證服務(wù)器給用戶返回一個成功的令牌token,主要在認證服務(wù)器中完成当辐,即圖中的認證系統(tǒng)抖僵,注意認證系統(tǒng)只能有一個
身份校驗: 這一環(huán)節(jié)是用戶攜帶token去訪問其他服務(wù)器時,在其他服務(wù)器中要對token的真?zhèn)芜M行檢驗缘揪,主要在資源服務(wù)器中完成耍群,即圖中的應(yīng)用系統(tǒng)2 3

3.JWT介紹
概念說明
從分布式認證流程中,我們不難發(fā)現(xiàn)寺晌,這中間起最關(guān)鍵作用的就是token世吨,token的安全與否澡刹,直接關(guān)系到系統(tǒng)的健壯性呻征,這里我們選擇使用JWT來實現(xiàn)token的生成和校驗。
JWT罢浇,全稱JSON Web Token陆赋,官網(wǎng)地址https://jwt.io沐祷,是一款出色的分布式身份校驗方案≡艿海可以生成token赖临,也可以解析檢驗token。
JWT生成的token由三部分組成:

  • 頭部:主要設(shè)置一些規(guī)范信息灾锯,簽名部分的編碼格式就在頭部中聲明兢榨。
  • 載荷:token中存放有效信息的部分,比如用戶名顺饮,用戶角色吵聪,過期時間等,但是不要放密碼兼雄,會泄露吟逝!
  • 簽名:將頭部與載荷分別采用base64編碼后,用“.”相連赦肋,再加入鹽块攒,最后使用頭部聲明的編碼類型進行編碼,就得到了簽名佃乘。

JWT生成token的安全性分析
從JWT生成的token組成上來看囱井,要想避免token被偽造,主要就得看簽名部分了趣避,而簽名部分又有三部分組成琅绅,其中頭部和載荷的base64編碼,幾乎是透明的鹅巍,毫無安全性可言千扶,那么最終守護token安全的重擔(dān)就落在了加入的鹽上面了!
試想:如果生成token所用的鹽與解析token時加入的鹽是一樣的骆捧。豈不是類似于中國人民銀行把人民幣防偽技術(shù)公開了澎羞?大家可以用這個鹽來解析token,就能用來偽造token敛苇。這時妆绞,我們就需要對鹽采用非對稱加密的方式進行加密,以達到生成token與校驗token方所用的鹽不一致的安全效果枫攀!
非對稱加密RSA介紹:
基本原理:同時生成兩把密鑰:私鑰公鑰括饶,私鑰隱秘保存,公鑰可以下發(fā)給信任客戶端
私鑰加密来涨,持有私鑰或公鑰才可以解密
公鑰加密图焰,持有私鑰才可解密
優(yōu)點: 安全,難以破解
缺點: 算法比較耗時蹦掐,為了安全技羔,可以接受
歷史: 三位數(shù)學(xué)家Rivest僵闯、Shamir 和 Adleman 設(shè)計了一種算法,可以實現(xiàn)非對稱加密藤滥。這種算法用他們?nèi)齻€人的名字縮寫:RSA鳖粟。

4.SpringSecurity整合JWT

  • 4.1 認證思路分析
    SpringSecurity主要是通過過濾器來實現(xiàn)功能的!我們要找到SpringSecurity實現(xiàn)認證和校驗身份的過濾器
    4.2 分析分布式認證流程
    用戶認證
    由于分布式項目拙绊,多數(shù)是前后端分離的架構(gòu)設(shè)計向图,我們要滿足可以接受異步post的認證請求參數(shù),需要修改UsernamePasswordAuthenticationFilter過濾器中attemptAuthentication方法标沪,讓其能夠接收請求體张漂。
    另外,默認successfulAuthentication方法在認證通過后谨娜,是把用戶信息直接放入session就完事了航攒,現(xiàn)在我們需要修改這個方法,在認證通過后生成token并返回給用戶趴梢。
    身份校驗
    原來BasicAuthenticationFilter過濾器中doFilterInternal方法校驗用戶是否登錄漠畜,就是看session中是否有用戶信息,我們要修改為坞靶,驗證用戶攜帶的token是否合法憔狞,并解析出用戶信息,交給SpringSecurity彰阴,以便于后續(xù)的授權(quán)功能可以正常使用

參考文章: https://mp.weixin.qq.com/s?__biz=Mzg2MjEwMjI1Mg==&mid=2247516734&idx=1&sn=966d166d3052f10b9310ff4014733669&chksm=ce0e35bdf979bcabbb75366e1bad32bdbf8f41d1dc80b8be6e39225bd708913ce2c93472f2fc&mpshare=1&scene=23&srcid=0602G1Eh5izWvt4jbaX9a81P&sharer_sharetime=1622628809523&sharer_shareid=f770d25bc57f1c2f9159f85750f854dc#rd

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瘾敢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子尿这,更是在濱河造成了極大的恐慌簇抵,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件射众,死亡現(xiàn)場離奇詭異碟摆,居然都是意外死亡,警方通過查閱死者的電腦和手機叨橱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門典蜕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人罗洗,你說我怎么就攤上這事愉舔。” “怎么了伙菜?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵轩缤,是天一觀的道長。 經(jīng)常有香客問我,道長典奉,這世上最難降的妖魔是什么躺翻? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任丧叽,我火速辦了婚禮卫玖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘踊淳。我一直安慰自己假瞬,他們只是感情好,可當我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布迂尝。 她就那樣靜靜地躺著脱茉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪垄开。 梳的紋絲不亂的頭發(fā)上琴许,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天,我揣著相機與錄音溉躲,去河邊找鬼榜田。 笑死,一個胖子當著我的面吹牛锻梳,可吹牛的內(nèi)容都是我干的箭券。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼疑枯,長吁一口氣:“原來是場噩夢啊……” “哼辩块!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起荆永,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤废亭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后具钥,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體滔以,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年氓拼,在試婚紗的時候發(fā)現(xiàn)自己被綠了你画。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡桃漾,死狀恐怖坏匪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情撬统,我是刑警寧澤适滓,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站恋追,受9級特大地震影響凭迹,放射性物質(zhì)發(fā)生泄漏罚屋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一嗅绸、第九天 我趴在偏房一處隱蔽的房頂上張望脾猛。 院中可真熱鬧,春花似錦鱼鸠、人聲如沸猛拴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽愉昆。三九已至,卻和暖如春麻蹋,著一層夾襖步出監(jiān)牢的瞬間跛溉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工扮授, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留芳室,地道東北人。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓糙箍,卻偏偏與公主長得像渤愁,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子深夯,可洞房花燭夜當晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容