總結之前寫過乙個小型論壇,關於許可權有乙個需求就是在判斷許可權的時候經常還要判斷分割槽id是否匹配, 某個角色的許可權只在其對應的分割槽有效,學習spring security後試著用spring security實現這個需求
因為判斷是需要使用者請求的分割槽引數,所以選擇方法層面的許可權管理,使用者擁有的許可權要儲存分割槽資訊所有要建立自己的grantedauthority,提供自定義accessdecisionvoter的實現類,獲取請求引數中的分割槽資訊,然後在進行判斷。
將角色名作為許可權,若角色名帶有_partition字尾認為角色許可權與分割槽關聯,partitionid屬性有效
**如下(示例):
@data
public class partitiongrantedauthority implements grantedauthority
/** * 將格式合理的字串轉化為對應的partitiongrantedauthority實體類
* @param authoritystrwithpartition 符合格式的字串authority與partitionid使用 - 相間隔
* @return authoritystrwithpartition
*/public static partitiongrantedauthority fromformatstr
(string authoritystrwithpartition)
partitiongrantedauthority authority = new partitiongrantedauthority()
; authority.authority = strings[0]
; authority.partitionid = strings[1]
;return authority;
} public partitiongrantedauthority()
public partitiongrantedauthority
(role role)
}
修改從roles轉化為authoritis的**
roles.
stream()
.map
(partitiongrantedauthority:
:new)
.collect
(collectors.
tolist()
);
再修改生成和解析jwttoken時的**,保證生成和解析token時partitionid這個屬性不會丟失
要求分割槽許可權的方法同時要求提供的引數中包含分割槽資訊,通過反射來獲取。具體實現基本可以照抄rolevoter只是進行額外的判斷
**如下(示例):
public class partitionvoter implements accessdecisionvoter
@override
public boolean supports
(configattribute attribute)
@override
public boolean supports
(class<
?> clazz)
@override
public int
vote
(authentication authentication, methodinvocation mi, collection attributes)
int result = access_abstain;
collection<
? extends grantedauthority> authorities = authentication.
getauthorities()
;for
(configattribute attribute : attributes)}}
}}return result;
}/**
* 從呼叫方法的實參中獲取partitionid
* 要求表示partitionid的域的name值為partitionid
** @param mi mi
* @return 返回partition_name_null表示引數中無partitionid資訊
*/private string getpartitionid
(methodinvocation mi)
catch (nosuchfieldexception ignored)
catch (illegalacces***ception e)
}return res;
}}
本來是想復用preauthorize的,但是它的解析過程實在沒辦法下手,所以使用已有@secured
註解標註需要的許可權即就可被partitionvoter處理。
問題:因為預設的delegatingmethodsecuritymetadatasource實現方式導致同時配置@preauthorize
和@secured
註解會導致後者的配置無法讀取,想讓二者同時生效必須完全重寫methodsecuritymetadatasource()
方法。
自定義globalmethodsecurityconfiguration的子類methodsecurityconfig,並新增@enableglobalmethodsecurity
註解,如果
securityconfig上也有@enableglobalmethodsecurity
註解會導致methodsecurityconfiguration失效,不知道為什麼。
還有乙個小問題就是預設的accessdecisionmanager的實現是包含rolevoter的,所以如果標註的許可權是以role_開頭會被rolevoter通過,我認為可以有這幾種解決方案
不要讓許可權帶有role_字首,但感覺有點不規範
把父類中accessdecisionmanager**抄一遍,但不新增rolevoter,但因為prepostenabled()等判斷方法子類是無法呼叫的,所以有點麻煩,而且**所表達的含有也不清楚
迭代accessdecisionmanager中的decisionvoters把rolevoter刪了,不知道為什麼感覺很蠢
把accessdecisionmanagerd的實現改為unanimousbased,讓partitionvoter擁有一票否決權,如果遇見一定不能設定一票否決的情況就不行了
我為了方便選擇最後一種
**如下(示例):
@configuration
@enableglobalmethodsecurity
(prepostenabled = true, securedenabled = true)
public class methodsecurityconfig extends globalmethodsecurityconfiguration
}
其實該有很多可以改的地方,例如應該寫乙個諸如grantedauthorityutil之類的類,所以和自定義grantedauthority進行的互動都通過這個類中的方法來進行,還有partition_role_edn_with引數不應該直接寫死在類中。不過因為寫這個只是為了學習spring security,寫完功能沒問題就懶得改了
spring security 安全框架
本文 http itblood.com spring security security framework.html 安全常識 acegi介紹 以宣告式方式為基於spring的web應用新增認證和授權控制 acegi體系結構 認證管理器 訪問控制管理器。認證 authenticationproce...
SpringSecurity認證流程
在之前的文章 springboot spring security 基本使用及個性化登入配置 中對springsecurity進行了簡單的使用介紹,基本上都是對於介面的介紹以及功能的實現。這一篇文章嘗試從原始碼的角度來上對使用者認證流程做乙個簡單的分析。在具體分析之前,我們可以先看看springse...
SpringSecurity使用技巧
1 鑑權處理頁通常包括四個方面的設定,分別是鑑權失敗 鑑權成功 未鑑權訪問 已鑑權但訪問了受保護許可權。如何自 定義這四類處理。鑑權失敗的預設處理頁面是 spring security login?login error 其預設處理類為 urlauthenticationfailurehandler...