開發(fā)Java應用項目的時候,安全管理通常來講是必不可少的功能。常用的安全管理框架有Apache Shiro和Spring Security,那么作為一名開發(fā)人員的話,該如何選擇自己的權限管理框架呢?
首先我們來看一看兩者的區(qū)別。
Apache Shiro是一個強大且易用的Java安全框架,能夠非常清晰的處理認證、授權、管理會話以及密碼加密等功能。他的API也非常易于理解的API,因此,對于初學者來說,非常容易上手。
它的特點包括:
· 易于理解的 Java Security API;
· 簡單的身份認證(登錄),支持多種數(shù)據源(LDAP,JDBC,Kerberos,ActiveDirectory等);
· 對角色的簡單的簽權(訪問控制),支持細粒度的簽權;
· 支持一級緩存,以提升應用程序的性能;
· 內置的基于 POJO 企業(yè)會話管理,適用于 Web 以及非 Web 的環(huán)境;
· 異構客戶端會話訪問;
· 非常簡單地加密 API;
· 不跟任何的框架或者容器捆綁,可以獨立運行。
Spring Security是一個能夠為基于Spring的企業(yè)應用系統(tǒng)提供聲明式的安全訪問控制解決方案的安全框架。它提供了一組可以在Spring應用上下文中配置的Bean,充分利用了Spring IoC(控制反轉),DI( 依賴注入)和AOP(面向切面編程)功能,為應用系統(tǒng)提供聲明式的安全訪問控制功能,減少了為企業(yè)系統(tǒng)安全控制編寫大量重復代碼的工作。它與Spring MVC能夠很好地集成,并配備了流行的安全算法實現(xiàn)捆綁在一起。Spring Security在我們進行用戶認證以及授予權限的時候,通過各種各樣的攔截器來控制權限的訪問,從而實現(xiàn)安全。
從功能上來講,shiro能實現(xiàn)的,Spring Security 基本都能實現(xiàn),依賴于Spring體系,但是好處是Spring全家桶的親兒子,集成上更加契合,在使用上,比shiro略負責。但是Shiro比Spring Security更容易使用,也就是實現(xiàn)上簡單一些,同時基本的授權認證Shiro也基本夠用。
從社區(qū)活躍度來說,Spring Security社區(qū)支持度更高,Spring社區(qū)的親兒子,支持力度和更新維護上有優(yōu)勢。相比之下Shiro的支持度就差了一點,但是依然還是有很多開發(fā)者在為Shiro做出貢獻。
而Shiro 功能強大、簡單、靈活。不跟任何的框架或者容器綁定,可以獨立運行。因此對于非Spring的項目,Shiro兼容性更高一些。
因此,從比較上來講,兩者的區(qū)別不是很大。使用的時候,如果開發(fā)框架全部采用Spring全家桶的話,那么用Spring Security會比較合適一些。而對于剛開始接觸安全管理框架或者是不用Spring全家桶的話,用Shiro比較好一些。
但是,同時我們也應該注意到,Shiro和Spring Security都已經誕生了十幾年了,隨著技術的演進發(fā)展,其基本框架也產生了一定局限性,尤其是對于前后端分離的框架來說,需要多做很多兼容性的工作。
在這種情況下,新的Java權限管理框架Sa-Token就應運而生了。
Sa-Token 是一個輕量級 Java 權限認證框架,主要解決:登錄認證、權限認證、Session會話、單點登錄、OAuth2.0、微服務網關鑒權 等一系列權限相關問題。
Sa-Token 的 API 設計非常簡單,以登錄認證為例,只需要兩行代碼就可以完成了:
// 在登錄時寫入當前會話的賬號id
StpUtil.login(10001);
// 然后在需要校驗登錄處調用以下方法:
// 如果當前會話未登錄,這句代碼會拋出 `NotLoginException` 異常
StpUtil.checkLogin();
再比如權限認證,如下代碼即可完成(只有具備 user:add 權限的會話才可以進入請求):
@SaCheckPermission(“user:add”)
@RequestMapping(“/user/insert”)
public String insert(SysUser user) {
// …
return “用戶增加”;
}
看吧,是不是很簡單,相比起Shrio和Spring Security繁瑣來說,簡單是懶人的福音。事實上,對于絕大部分的權限控制功能Sa-Token都能夠用一句話來完成。就像下面一樣。
StpUtil.login(10001); // 標記當前會話登錄的賬號id
StpUtil.getLoginId(); // 獲取當前會話登錄的賬號id
StpUtil.isLogin(); // 獲取當前會話是否已經登錄, 返回true或false
StpUtil.logout(); // 當前會話注銷登錄
StpUtil.kickout(10001); // 將賬號為10001的會話踢下線
StpUtil.hasRole(“super-admin”); // 查詢當前賬號是否含有指定角色標識, 返回true或false
StpUtil.hasPermission(“user:add”); // 查詢當前賬號是否含有指定權限, 返回true或false
StpUtil.getSession(); // 獲取當前賬號id的Session
StpUtil.getSessionByLoginId(10001); // 獲取賬號id為10001的Session
StpUtil.getTokenValueByLoginId(10001); // 獲取賬號id為10001的token令牌值
StpUtil.login(10001, “PC”); // 指定設備標識登錄,常用于“同端互斥登錄”
StpUtil.kickout(10001, “PC”); // 指定賬號指定設備標識踢下線 (不同端不受影響)
StpUtil.openSafe(120); // 在當前會話開啟二級認證,有效期為120秒
StpUtil.checkSafe(); // 校驗當前會話是否處于二級認證有效期內,校驗失敗會拋出異常
StpUtil.switchTo(10044); // 將當前會話身份臨時切換為其它賬號
因此,技術發(fā)展日新月異,作為一名程序員,要緊跟時代的發(fā)展,才能使自己不至于落后。