0

在我们的应用程序中,我们有以下内容:

<intercept-url pattern="/app/**" access="ROLE_ADMIN,ROLE_USER,ROLE_CUST_ADMIN" />

但是,在我们的应用程序中,我们也可以创建自定义角色,并且,当自定义角色的用户(例如)ROLE_LIMITED_USER尝试登录时,访问被拒绝。

如何在不列出角色的情况下保护应用程序?或者我怎样才能让它接受一个模式ROLE_*

我尝试了以下方法:

<intercept-url pattern="/app/**" access="IS_AUTHENTICATED_FULLY" />

但是,这会导致会话超时并且需要用户登录。在更改之前,会记住用户登录。

感谢任何解决方案谢谢

4

2 回答 2

8

几件事:

  1. 您在应用程序中访问功能所需的角色不应更改 - 更多地将它们视为“权限”而不是“角色”。(这里的 Spring Security 默认值可能用词不当。)然后您可以将权限集映射到角色(通过您自己的代码),允许将自定义角色创建为不同的权限包,但您正在编码的实际权限/检查是静态的 - 它们不会改变。当用户通过身份验证时,GrantedAuthority您在 中填充的 s集UserDetails应该是基于用户分配的角色的合并权限集合。

  2. 也就是说,我认为您仍然可以通过使用基于表达式的访问控制来做您想做的事情,而无需更改安全模型。假设您使用的是安全命名空间(即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>
    

请注意,此代码段尚未经过测试,我很确定第三个intercept-url示例不会按原样工作,但应该非常接近。(它试图过滤Collection<GrantedAuthority>以开头的权限ROLE_并确保过滤后的列表不为空。)

我的猜测是,使用 2nd 并在代码中进行任何进一步的自定义检查会更容易intercept-url,您可以通过以下方式访问当前的SecurityContext//Authentication主体:

SecurityContextHolder.getContext()

希望这可以帮助。

在这里也要注意类似的问题: Spring Security Authorize Access Role with a Wildcard

于 2013-06-08T04:55:33.393 回答
0

在您的类中使用 Spring 的@PreAuthorize注释,并通过SpEL引用自定义权限评估器。不要担心构建表达式解析器,因为您可以简单地从注释中引用布尔方法:

@PreAuthorize("@myCustomClass.booleanMethod(param1, param2, #passedParam) and isAuthenticated()")
myMethod(passedParam) {
    //do something
}

然后,在自定义类中,定义布尔方法,它可以随心所欲地处理您的角色(权限)——包括访问数据库以发现您新添加的角色。

您将无法即时将新角色添加到 XML 配置中,因此如果您的问题与新角色创建有关(似乎是这种情况),您需要类似上述内容才能实现。使用 SpEL 和自定义布尔方法,您可以访问可以添加到应用程序中的可能无限的限制和要求集。

于 2013-06-08T05:29:45.120 回答