如何使用Defender優雅的管理權限?

何爲權限管理

權限管理已經不知不覺深刻到了咱們生活的每個角落,例如地鐵進站的閘機,高速公路上的過路費,停車場的槓桿等等等等。git

做爲一名開發人員,權限二字對咱們的映像更加深入,不管任何系統,都多多少少與權限管理會沾上關係!什麼?你的系統和權限不沾邊......好吧,你的代碼拉取權限總得有吧!若是尚未的話,你登上掘金看到這篇文章並點了一個贊這個過程就須要好屢次權限校驗。好了扯遠了,咱們迴歸正題,這裏使用一張圖來簡單展現web系統的權限是什麼樣子:github

看完以後,是否是感受很簡單,不錯,權限管理並不難,咱們只須要將校驗這一環節進行開發便可,實現方式也有不少種:web

方案一:組件封裝

咱們能夠將權限校驗的整個過程組件化,例如組件名爲AuthComponent,以後再全部須要權限校驗的接口對應的方法的開頭,調用AuthComponentverify方法進行校驗,根據結果作不一樣的業務處理!spring

  • 優勢:貌似能達到主要目的,並且很是靈活~
  • 缺點:代碼冗餘,低內聚,高耦合,不易於維護。

方案二:通用處理

在方案一的基礎上咱們稍加改造,例如使用AOP對須要校驗的接口作個切面,在方法執行前咱們使用AuthComponent校驗一下便可,這樣咱們的代碼就更方便維護了!api

  • 優勢:彌補了方案一的缺點。
  • 缺點:太過通用化,很難兼容全部的狀況,不靈活。

方案三:自定義註解

咱們將方案一和方案二結合一下,取一靈活,取二通用,咱們自定義一個名爲@Auth的註解,而且它須要傳一個參數,咱們這裏直徑定義爲枚舉類Level,簡單結構以下:bash

public enum Level { LOGIN, ADMIN }
複製代碼

以後咱們定義一個註解切面,切向攜帶@Auth的方法,在方法執行前根據value值的內容,也就是Level的值去作不一樣的權限管理便可。網絡

  • 優勢:靈活可控,通用性還行。
  • 缺點:缺少組件化,結構零散,不易複用,對於多種場景下須要制定多個切面,不優雅!

方案四:使用框架

這是最簡單的方法,例如優秀的開源shirospring-Security等均可以知足咱們的需求,惟一的區別是框架的輕重及使用方式!框架

如何更優雅的管理權限

想必不少同窗都在使用第四種方案,也有很多的小夥伴在使用方案三,對於缺點明顯的方案一和二,使用的應該不多。ide

若是咱們的服務並不須要那麼重的權限管理框架去解決權限問題,又不想不優雅的自定義註解去實現時,咱們該怎麼辦呢?spring-boot

不妨試試 Defender

Defender是什麼

defender是一款全面擁抱spring-boot的輕量級,高靈活,高可用的權限框架。若是平常中咱們須要更加優雅的對服務增長權限管理,那麼defender正合適!

它能夠免除咱們重複編寫自定義註解和切面,只須要調用簡單的API便可靈活的指定不一樣模式的防護網絡。

爲什麼優雅

defender提供小巧靈活的API去制定你想要的權限過濾網絡,提供不少種防護模式,咱們能夠經過調用簡單的api是使用構建不一樣模式的校驗器,從而迅速完成權限的管理:

@Configuration
@EnableDefender("* org.nico.trap.controller..*.*(..)")
public class DefenderTestConfig {
	@Bean
	public Defender init(){
		return Defender.getInstance()
				.registry(Guarder.builder(GuarderType.URI)
						.pattern("POST /user/*")
						.preventer(caller -> {
							return caller.getRequest().getHeader("token") == null 
								? Result.pass() : Result.notpass("error");
						}))
				.ready();
	}
}
複製代碼

上述代碼的做用是對請求符合POST類型且URI前綴爲/user/的全部接口作了權限管理。

另外,咱們可使用lambda簡單完成權限校驗邏輯,又或者使用匿名類實現複雜校驗邏輯:

Guarder.builder(GuarderType.ANNOTATION)
		.pattern("org.nico.trap.controller")
		.preventer(new AbstractPreventer() {
			
			@Autowired
			private AuthComponent authComponent;
			
			@Override
			public Result detection(Caller caller) {
				String identity = caller.getAccess().value();
				if(! identity.equals(AuthConst.VISITOR)) {
					UserBo user = authComponent.getUser();
					if(user != null) {
						if(identity.equals(AuthConst.ADMIN)){
							if(user.getRuleType() == null) {
								return Result.notpass(new ResponseVo<>(ResponseCode.ERROR_ON_USER_IDENTITY_MISMATCH));
							}
						}
					}else {
						return Result.notpass(new ResponseVo<>(ResponseCode.ERROR_ON_LOGIN_INVALID));
					}
				}
				return Result.pass();
			}
		})
複製代碼

其中GuarderType.URIGuarderType.ANNOTATION分別表明URI ANT匹配模式和註解模式,後者是方案三的實現,defender提供簡單優雅的api將各類模式的權限校驗方式集合在一塊兒。

相比shirospring-securitydefender顯得更加輕便靈活,由於它並無提供一系列權限更具體的管理實現,而是將校驗的實現開放一個接口面向開發者,整體代碼大小不超過21k,顯然對於輕量級的權限管理,defender更加適合!

各類傳送門

defender剛剛起步,若是你們有興趣能夠將之集成在您的開發環境嘗一下鮮,項目地址以下

Defender傳送門

官方也提供有簡單的使用文檔

中文文檔

English Document

若是您感受不錯,也想參與貢獻

如何貢獻

相關文章
相關標籤/搜索