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 = ""
}
}
添加回答
举报