单点登陆设计
文章目錄
- 一、登陸流程怎么設(shè)計(jì)和編碼
- 1.1名詞掃盲
- 1.2登陸設(shè)計(jì)
- 1.3 token安全性
一、登陸流程怎么設(shè)計(jì)和編碼
1.1名詞掃盲
- 認(rèn)證中心:一個(gè)獨(dú)立的服務(wù),用于統(tǒng)一認(rèn)證和統(tǒng)一權(quán)限
- 客戶端:任何一個(gè)子系統(tǒng)
- 過濾器:客戶端common類,任何客戶端都需要依賴,所有有關(guān)權(quán)限的操作都要經(jīng)過過濾器進(jìn)行委托認(rèn)證
- 全局會(huì)話:認(rèn)證中心和瀏覽器的會(huì)話
- 局部會(huì)話:客戶端自己的會(huì)話(客戶端和瀏覽器的會(huì)話)
局部會(huì)話存在,全局會(huì)話一定存在
全局會(huì)話存在,局部會(huì)話不一定存在
全局會(huì)話銷毀,局部會(huì)話必須銷毀
1.2登陸設(shè)計(jì)
第一步:客戶端發(fā)送賬號密碼到認(rèn)證中心。(客戶端無須編寫登陸邏輯,只要post認(rèn)證中心的loginUrl即可)
第二步:認(rèn)證中心驗(yàn)證賬號密碼生成全局會(huì)話和token返回給客戶端
第三步:客戶端接收到token,經(jīng)過過濾器將token發(fā)送到認(rèn)證中心驗(yàn)證有效性
第四步:驗(yàn)證成功進(jìn)行登陸,建立客戶端局部會(huì)話
下面結(jié)合時(shí)序圖和代碼幫助理解
shiro filter代碼片段,此方法相當(dāng)于時(shí)序圖中的filter角色
/**token是否失效,token失效有兩個(gè)場景** 一:子系統(tǒng)會(huì)話還存在的時(shí)候重復(fù)登陸,導(dǎo)致全局token不一致。** 二:認(rèn)證中心強(qiáng)制下線*/if(isLogin(request)) {//客戶端已經(jīng)登陸(局部會(huì)話已經(jīng)存在)if(!tokenAvailable()){//token失效//當(dāng)前token失效后,進(jìn)行token驗(yàn)證,如果地址含有token,則重新進(jìn)行驗(yàn)證和登陸if(reLoginIfTokenEnable(request, response)){return true;}else{//已經(jīng)登陸并且token無效,此處跳轉(zhuǎn)到登陸界面return false;}}return true;}//url沒有攜帶token參數(shù),則向認(rèn)證中心申請tokenif(noHasToken(request)){return doAuthBySsoServer(request,response);}//已經(jīng)獲取到認(rèn)證中心token,對token進(jìn)行驗(yàn)證和登陸,建立局部會(huì)話if(isAuth(request)){return loginBySsoToken(request,response,request.getParameter("token"));}return true;}1.3 token安全性
假如token暴漏或者通過抓包取到token進(jìn)行模擬登陸怎么辦?通過設(shè)計(jì)上可以避免這種情況,首先token是一個(gè)對象,可以添加一個(gè)alreadyVerify布爾屬性,判斷該token是否已經(jīng)被驗(yàn)證過了,已經(jīng)驗(yàn)證過的token將不在進(jìn)行第二次驗(yàn)證。原理很簡單,只要某一個(gè)子系統(tǒng)登陸,那么alreadyVerify就為true,表明已經(jīng)驗(yàn)證過。其他電腦抓取到token也是無法登陸的。那么假如同一個(gè)瀏覽器要登陸其他子系統(tǒng)呢?上面的設(shè)計(jì)限制了只能登陸一個(gè)子系統(tǒng)(因?yàn)閍lreadyVerify被設(shè)置為true)。其實(shí)在同一個(gè)瀏覽器,全局會(huì)話是存在的,只要判斷全局會(huì)話存在,認(rèn)證中心可以改變alreadyVerify屬性令其為false,這樣其他子系統(tǒng)就可以校驗(yàn)token成功了,下面是認(rèn)證中心校驗(yàn)token的代碼
public boolean verify(String token) {Token tk = redis.get(token);if(tk==null){//toklen不存在,token校驗(yàn)失效return false;}if(tk.isAlreadyVerify())return false;//tk已經(jīng)被使用過,失效if(tk.getToken().equals(token)) {//驗(yàn)證通過return true;} return false;}點(diǎn)擊下面閱讀
redis在線用戶設(shè)計(jì)
總結(jié)
- 上一篇: coreseek java_使用pyth
- 下一篇: mybatis学习(44):二级缓存1