Spring Security:如何在使用多个“http”元素时为给定 URL 授权用户?

Posted

技术标签:

【中文标题】Spring Security:如何在使用多个“http”元素时为给定 URL 授权用户?【英文标题】:Spring Security: How to authorize user for a given URL when using multiple `http` elements? 【发布时间】:2013-07-07 08:54:59 【问题描述】:

我有一个以模块化方式构建的 Spring MVC Web 应用程序。添加到网站的每个模块都可以为用户授权定义自己的安全元素(在 xml 中使用 http 命名空间),这很好并且有效。

我现在需要以编程方式检查当前用户是否有权访问给定的 URL。我已经搜索和搜索并找到了许多对 WebInvocationPrivilegeEvaluator 的引用,这很好,除了我的应用程序目前有 6 个并且我不确定要使用哪一个(它有 6 个 <http: 元素)。我尝试循环所有 6 个并对每个执行检查,但这会返回奇怪的结果。

例子:

我可以使用以下方法获取所有 bean:

private Collection<WebInvocationPrivilegeEvaluator> privEvals;
....
privEvals = (List<WebInvocationPrivilegeEvaluator>) applicationContext.getBeansOfType(WebInvocationPrivilegeEvaluator.class).values();

然后像这样循环检查:

public void checkForUrl(String url) 
    for(WebInvocationPrivilegeEvaluator privEval:privEvals) 
        System.out.println(privEval.isAllowed(url, SecurityContextHolder.getContext().getAuthentication()));
    

示例 1:用户被授权访问 URL,打印: 假的 假的 真的 真的 真的 真的

示例 2:同一用户未获得 URL 授权,打印: 假的 假 真的 真的 真的 真的

但如果我尝试浏览 URL,我会得到第二个 URL 的正确 403

更新

如果我使用接受上下文的WebInvocationPrivilegeEvaluator 的其他方法,我会得到相同的结果。我已经尝试了许多使用不同 http 元素保护它们的 URL,并且返回相同的布尔值(以相同的顺序)。

如果我使用分配了不同角色的不同 用户,我会遇到同样的问题,即不同 URL 的结果总是相同的(当用户有权或无权访问它们时) , 除了这次打印以下内容: 假 真的 真的 真的 假 真的

更新

我曾尝试使用&lt;sec:authorize 标记,但结果更奇怪,看起来好像它只是使用第一个WebInvocationPrivilegeEvaluator

【问题讨论】:

您是否尝试过 WebInvocationPrivilegeEvaluator 的另一种采用上下文路径的方法? 感谢您的评论。我已经更新了我的问题作为回应,但简而言之,我有,但它不起作用。我开始认为我应该只实现自己的测试来 ping URL 并检查响应,尽管我真的不想这样做,因为它会增加延迟...... 好的。 authorize JSP 标签利用了它,我已经用过好几次了。示例:。 AbstractAuthorizeTag 的 authorizeUsingUrlCheck 方法使用相同的代码来检查授权。 这也行不通,它似乎向除一个以外的所有用户返回false,用户得到一些true。因此我认为它只是使用WebInvocationPrivilegeEvaluator 之一 是的。 AbstractAuthorizeTag 使用第一个。查看它的 getPrivilegeEvaluator() 方法。 【参考方案1】:

旧帖子,但我遇到了这个问题,但没有找到真正的答案。 我的实现是使用特定角色选择良好的安全领域来识别领域。

我得到了 WebInvocationPrivilegeEvaluator 和 FilterSecurityInterceptor

    ApplicationContext context = AppContext.getApplicationContext(); 
    Map<String, WebInvocationPrivilegeEvaluator> wipes = context.getBeansOfType(WebInvocationPrivilegeEvaluator.class);
    Map<String, FilterSecurityInterceptor> filters = context.getBeansOfType(FilterSecurityInterceptor.class);

我浏览每一个并在用于领域的特定角色上测试 FilterSecurityInterceptor:

    for (int i = 0; i < wipes.size(); i++) 
        privilegeEvaluator=(DefaultWebInvocationPrivilegeEvaluator) wipes.values().toArray()[i];
        FilterSecurityInterceptor filter = (FilterSecurityInterceptor) filters.values().toArray()[i];
        if (filter.getSecurityMetadataSource().getAllConfigAttributes().toString().contains("hasRole('SPECIFIC_ROLE')")) return privilegeEvaluator;
    

【讨论】:

以上是关于Spring Security:如何在使用多个“http”元素时为给定 URL 授权用户?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring WebFlux Security(Reactive Spring Security)配置中将多个用户角色添加到单个 pathMatcher/Route?

Spring Security:如何在使用多个“http”元素时为给定 URL 授权用户?

如何使用 Spring Security 跨多个基于 JVM 的应用程序实现单点登录

如何从多个服务器获取与 Spring Security 和 Spring Session 相同的会话

Spring Security - 如何禁用同一浏览器的多个选项卡之间的相同会话共享?

在多个服务器上使用 Spring Security 和 Spring Redis Session