在我们的应用中,我们有以下内容:
<intercept-url pattern="/app/**" access="ROLE_ADMIN,ROLE_USER,ROLE_CUST_ADMIN" />
但是,在我们的应用程序中,我们也可以创建自定义角色,并且当自定义角色的用户(例如ROLE_LIMITED_USER
尝试登录时)访问被拒绝。
如何在不列出角色的情况下保护应用程序?或者我如何让它接受模式ROLE_*
?
我尝试了以下内容:
<intercept-url pattern="/app/**" access="IS_AUTHENTICATED_FULLY" />
但是,这导致会话超时,用户需要登录。在更改之前,记住了用户登录。
欣赏任何解决方案 感谢
答案 0 :(得分:8)
一些事情:
您在应用中访问功能所需的角色不应更改 - 将其视为“权限”而非“角色”。 (此处的Spring Security默认值可能用词不当。)然后,您可以将权限集映射到角色(通过您自己的代码),允许将自定义角色创建为不同的权限包,但您正在编码的实际权限/检查是静态的 - 它们不会改变。对用户进行身份验证后,您在GrantedAuthority
中填充的UserDetails
集应该是基于用户指定的角色权限的合并集合>
尽管如此,我认为您仍然可以使用Expression-Based Access Control在不更改安全模型的情况下执行您想要的操作。假设您正在使用安全名称空间(即xmlns="http://www.springframework.org/schema/security"
),那么您需要在use-expressions="true"
元素上设置<http>
并将access
属性值更改为SpEL表达式,例如为:
<http use-expressions="true">
<intercept-url pattern="/app/**" access="hasAnyRole('ROLE_ADMIN','ROLE_USER','ROLE_CUST_ADMIN')" />
<intercept-url pattern="/other1/**" access="isAuthenticated()" />
<intercept-url pattern="/other2/**" access="authentication.authorities.?[authority.startsWith('ROLE_')].size() != 0" />
</http>
请注意,此代码段尚未经过测试,我非常确定第3个intercept-url
示例不会按原样运行,但应该非常接近。 (它正在尝试将Collection<GrantedAuthority>
过滤到以ROLE_
开头的权限,并确保过滤后的列表不为空。)
我的猜测是,使用第二个intercept-url
会更容易,并在代码中进行任何进一步的自定义检查,您可以在其中访问当前的SecurityContext
/ Authentication
/主体通过:
SecurityContextHolder.getContext()
希望这有帮助。
此处也请注意类似的问题: Spring Security Authorize Access Role with a Wildcard
答案 1 :(得分:0)
在类中使用Spring的@PreAuthorize
注释,并通过SpEL引用自定义权限评估程序。不要担心构建表达式解析器,因为您可以简单地从注释中引用布尔方法:
@PreAuthorize("@myCustomClass.booleanMethod(param1, param2, #passedParam) and isAuthenticated()")
myMethod(passedParam) {
//do something
}
然后,在自定义类中,定义布尔方法,它可以处理您喜欢的角色(权限) - 包括访问数据库以发现新添加的角色。
您将无法动态地将新角色添加到XML配置中,因此,如果您的问题与新角色创建(似乎是这种情况)有关,那么您需要具备上述内容才能实现发生。使用SpEL和自定义布尔方法,您可以访问可以添加到应用程序中的无限限制和要求。