1 回答

TA貢獻1900條經驗 獲得超5個贊
簡而言之
授予的權限不會顯示ROLE_-prefix,因此會被RoleVoter.
將 替換為RoleVoter具有空前綴的自定義實現解決了該問題。
全文
現在這留下了為什么我們可以訪問視圖的問題。解釋很簡單,但需要更多的上下文。
我們正在努力將 Thorntail 應用程序遷移到 Spring Boot。
我們正在使用 Vaadin 8(因為我們有遺留的 Vaadin 7 東西,我們還沒有設法擺脫它,需要支持)。
所以?
Vaadin 是一個單頁框架,Vaadin 8 有這種討厭的視圖引用方式,即它使用#!根 url(例如https://<host>:<port>/#!foo/bar/baz/...)。
之后什么#都沒有發送到服務器,這意味著我們無法區分訪問/和訪問/#!foo/bar/baz/...
因此,我們不能使用 Spring Security 來保護對視圖的訪問。
并且我們有一個 Vaadin 視圖,我們需要允許未經身份驗證的訪問。
因此,我們被迫允許對/. (MainUI處理所有傳入請求的)將檢查用戶是否已通過身份驗證,如果未通過身份驗證,則重定向到登錄頁面。
對視圖本身的訪問由 Vaadin 保護,而不是 Spring。將SpringViewProvider找不到View用戶無權訪問的內容(因此,用戶無法導航到那里)。
但是,只要我們在該視圖上調用方法,Spring 安全性就會介入并執行訪問檢查。正是這些檢查失敗了,因為授予的權限沒有 Spring 預期的“ROLE_”前綴。(我原以為這只是一個約定,但事實并非如此;RoleVoter實際上忽略了不顯示前綴的權限,因此您必須那樣做,或者您必須提供自己的RoleVoter.)
解決方案相對簡單......
@Configuration
@EnableGlobalMethodSecurity(
securedEnabled = true,
prePostEnabled = true,
proxyTargetClass = true
)
class GlobalSecurityConfiguration : GlobalMethodSecurityConfiguration(){
override fun accessDecisionManager(): AccessDecisionManager {
return (super.accessDecisionManager() as AffirmativeBased).apply {
decisionVoters.replaceAll {
when(it){
is RoleVoter -> MyRoleVoter()
else -> it
}
}
}
}
}
在哪里
class MyRoleVoter : RoleVoter(){
init {
rolePrefix = ""
}
}
添加回答
舉報