聊聊 Spring Security 的新接口 AuthorizationManager
Spring Security 5.5 增加了一個新的授權管理器接口AuthorizationManager,它讓動態權限的控制接口化了,更加方便我們使用了,今天就來分享以下最新的研究成果,一鍵四連走起。
搶一個玩玩吧,別忘了分享給別的同學們。
AuthorizationManager
它用來檢查當前認證信息Authentication是否可以訪問特定對象T。AuthorizationManager將訪問決策抽象更加泛化。
@FunctionalInterface
public interface AuthorizationManager<T> {
default void verify(Supplier<Authentication> authentication, T object) {
AuthorizationDecision decision = check(authentication, object);
// 授權決策沒有經過允許就403
if (decision != null && !decision.isGranted()) {
throw new AccessDeniedException("Access Denied");
}
// todo 沒有null 的情況
}
// 鉤子方法。
@Nullable
AuthorizationDecision check(Supplier<Authentication> authentication, T object);
}
我們只需要實現鉤子方法check就可以了,它將當前提供的認證信息authentication和泛化對象T進行權限檢查,并返回AuthorizationDecision,AuthorizationDecision.isGranted將決定是否能夠訪問當前資源。AuthorizationManager提供了兩種使用方式。
基于配置
為了使用AuthorizationManager,引入了相關配置是AuthorizeHttpRequestsConfigurer,這個配置類非常類似于第九章中的基于表達式的訪問控制。
基于AuthorizationManager的訪問控制.png
在Spring Security 5.5中,我們就可以這樣去實現了:
// 注意和 httpSecurity.authorizeRequests的區別
httpSecurity.authorizeHttpRequests()
.anyRequest()
.access((authenticationSupplier, requestAuthorizationContext) -> {
// 當前用戶的權限信息 比如角色
Collection<? extends GrantedAuthority> authorities = authenticationSupplier.get().getAuthorities();
// 當前請求上下文
// 我們可以獲取攜帶的參數
Map<String, String> variables = requestAuthorizationContext.getVariables();
// 我們可以獲取原始request對象
HttpServletRequest request = requestAuthorizationContext.getRequest();
//todo 根據這些信息 和業務寫邏輯即可 最終決定是否授權 isGranted
boolean isGranted = true;
return new AuthorizationDecision(isGranted);
});
這樣門檻是不是低多了呢?同樣地,它也可以作用于注解。
基于注解
AuthorizationManager還提供了基于注解的使用方式。但是在了解這種方式之前我們先來看看它的實現類關系:
AuthorizationManager的實現
胖哥發現這一點也是從AuthorizationManager的實現中倒推出來的,最終發現了@EnableMethodSecurity這個注解,它的用法和@EnableGlobalMethodSecurity類似,對同樣的三種注解(參見EnableGlobalMethodSecurity)進行了支持。用法也幾乎一樣,開啟注解即可使用:
@EnableMethodSecurity(
securedEnabled = true,
jsr250Enabled = true)
public class MethodSecurityConfig {
}
例子就不在這里重復了。