SpringBoot整合SpringSecurityOauth2实现鉴权
SpringBoot整合SpringSecurityOauth2實(shí)現(xiàn)鑒權(quán)-動態(tài)權(quán)限
寫在前面
思考:為什么需要鑒權(quán)呢 ?
系統(tǒng)開發(fā)好上線后,API接口會暴露在互聯(lián)網(wǎng)上會存在一定的安全風(fēng)險(xiǎn) ,例如:爬蟲、惡意訪問等。因此,我們需要對非開放API接口進(jìn)行用戶鑒權(quán) ,鑒權(quán)通過之后再允許調(diào)用。
準(zhǔn)備
spring-boot:2.1.4.RELEASE
spring-security-oauth2:2.3.3.RELEASE(如果要使用源碼,不要隨意改動這個(gè)版本號,因?yàn)?.4往上的寫法不一樣了)
mysql :5.7
效果展示
這邊只用了postman做測試,暫時(shí)未使用前端頁面來對接 ,下個(gè)版本角色菜單權(quán)限分配的會有頁面的展示
1 、訪問開放接口 http://localhost:7000/open/hello

2 、不帶token訪問受保護(hù)接口 http://localhost:7000/admin/user/info

3 、登錄后獲取token ,帶上token訪問,成功返回了當(dāng)前的登錄用戶信息


實(shí)現(xiàn)
oauth2一共有四種模式,這邊就不做講解了,網(wǎng)上搜一搜 ,千篇一律
因?yàn)楝F(xiàn)在只考慮做單方應(yīng)用的,所以使用的是密碼模式 。
后面會出一篇SpringCloud+Oauth2的文章 ,網(wǎng)關(guān)鑒權(quán)
講一下幾個(gè)點(diǎn)吧
1 、攔截器配置動態(tài)權(quán)限

新建一個(gè) MySecurityFilter類,繼承AbstractSecurityInterceptor,并實(shí)現(xiàn)Filter接口
初始化,自定義訪問決策管理器
@PostConstruct public void init(){ super.setAuthenticationManager(authenticationManager); super.setAccessDecisionManager(myAccessDecisionManager); } 自定義 過濾器調(diào)用安全元數(shù)據(jù)源
@Overridepublic SecurityMetadataSource obtainSecurityMetadataSource() { return this.mySecurityMetadataSource;}先來看一下自定義過濾器調(diào)用安全元數(shù)據(jù)源的核心代碼
以下代碼是用來獲取到當(dāng)前請求進(jìn)來所需要的權(quán)限(角色)

/** * 獲得當(dāng)前請求所需要的角色 * @param object * @return * @throws IllegalArgumentException */ @Override public CollectiongetAttributes(Object object) throws IllegalArgumentException { String requestUrl = ((FilterInvocation) object).getRequestUrl(); if (IS_CHANGE_SECURITY) { loadResourceDefine(); } if (requestUrl.indexOf("?") >-1) { requestUrl = requestUrl.substring(0, requestUrl.indexOf("?")); } UrlPathMatcher matcher = new UrlPathMatcher(); List 
再來看一下自定義訪問決策管理器核心代碼 ,這段代碼主要是判斷當(dāng)前登錄用戶(當(dāng)前登錄用戶所擁有的角色會在最后一項(xiàng)寫到)是否擁有該權(quán)限角色

@Override public void decide(Authentication authentication, Object o, CollectionconfigAttributes) throws AccessDeniedException, InsufficientAuthenticationException { if(configAttributes == null){ //屬于白名單的 ,不需要權(quán)限 return; } Iteratoriterator = configAttributes.iterator(); while (iterator.hasNext()){ ConfigAttribute configAttribute = iterator.next(); String needPermission = configAttribute.getAttribute(); for (GrantedAuthority ga: authentication.getAuthorities()) { if(needPermission.equals(ga.getAuthority())){ //有權(quán)限