#背景: 由於公司前端引進新的技術react,改變了傳統的jsp模式,逐漸走上前後端分離的,並且隨著小程序,手機端業務的發展,越來越多的項目在開始往上面遷移,這就導致了權限問題。於是也就開啟了sso項目,一個人挖坑一個人填,終於是上線了。 #技術選擇 沒人指引,沒人會,導致了我現在百度裡面搜索了sso單點登錄,當時發現的是有個鑑權驗證的,需要第三方服務,cas實現,搞了一天,門都沒摸到,淘汰。後來在網上看到有人用shiro來做sso系統,然後開啟了shiro的瞭解之路。 #前言 我介紹更多的是我機遇shiro做的sso項目,對於shiro是啥,網上很多都有介紹,源碼我沒看,只知道他大概的實現原理,所以本人是小白一名,深入理解不了,見諒。 #sso系統設想 #####登錄 當用戶登錄的時候,登錄驗證後,把userInfo信息和一個token對應(UUID生成),放入redis中token為key,userInfo為value,並且把token返回給前端,要求前端每次訪問數據必須請求頭中放token #####鑑權 提供一個HTTP接口,讓各個系統都放入到filter裡面,每次數據接口請求,需要傳遞我token以及當前數據請求路徑,sso判斷是否有權限請求該接口, #需求 sso需要驗證登錄,需要驗證數據請求權限,需要支持分佈式部署 #實現 #####登錄
- 自定義Realm
當調用 SecurityUtils.getSubject().login(ssoUserNameToken)的時候,會調用重寫的方法
#####鑑權
- 自定義PermissionResolver
/**
*
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//該處為偽代碼
UserInfo userInfo = (UserInfo) SecurityUtils.getSubject().getPrincipal();
byte[] value = redisClient.get(userInfo.getToken());
if (value != null) {
userInfo = SerializeUtil.deserialize(value, UserInfo.class);
}
String key = SsoConstants.REDIS_ROLE_KEY + userInfo.getToken() + "-" + userInfo.getWebId();
Set
allPermissions = new HashSet<>(); byte[] bytes = redisClient.get(key);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setStringPermissions(allPermissions);
return info;
}
#####分佈式部署 必須重寫shiro的sessionDAO的管理,我這個是在github上面,有個大哥寫的案例,現在找不到了,很感謝大哥給我的啟發
重寫類
public class RedisCacheSessionDAO extends AbstractSessionDAO {
//該處需要重寫抽象方法
}
#攔截請求 運用shiro的請求攔截,自定義了一些攔截方法
/login/** = anon
/logout/** = logout
/static/**= anon
/** = token,validate,expire
token:驗證只能請求token的鑑權路徑,其他路徑一律攔截返回錯誤 validate:驗證是否有token,token是否有效 expire:延長用戶token過期時間 #結束語 以上是我花費1個月研究出來的sso系統,沒人做技術指導,有的只是需求,有的只是對技術的執著,我不知道我這種實現方式有什麼不妥,目前系統已經上線允許,也許是沒人搞我們系統,也許是走了狗屎運,目前運行一切正常。
轉
閱讀更多 JAVA技術開發 的文章