当前位置: 首页 > 面试题库 >

Spring Security-具有请求参数规则的网址被忽略

易焱
2023-03-14
问题内容

我有一个使用Spring Security的Web应用程序。它使用<intercept-url ../>元素描述不同URL的访问过滤器。默认情况下,这不考虑url的请求参数。我需要根据请求参数设置URL的自定义安全规则。所以我做了以下工作:

1)我创建了一个bean后处理器类,它将为spring安全机制启用request parameters选项:

<beans:beans>
    . . .
    <beans:bean class="MySecurityBeanPostProcessor">
        <beans:property name="stripQueryStringFromUrls" value="false" />
    </beans:bean>
    . . .
</beans:beans>

和代码:

public class MySecurityBeanPostProcessor implements BeanPostProcessor {

    private Boolean stripQueryStringFromUrls = null;

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof DefaultFilterInvocationSecurityMetadataSource && stripQueryStringFromUrls != null) {
            ((DefaultFilterInvocationSecurityMetadataSource) bean)
                .setStripQueryStringFromUrls(stripQueryStringFromUrls.booleanValue());
        }
        return bean;
    }

    // code stripped for clarity
}

这应该设置弹簧安全性元数据源以考虑请求参数。我已经调试了上面的代码,并且stripQueryStringFromUrls正在设置属性。

2)在我的安全上下文xml中,我具有以下定义:

<intercept-url pattern="/myUrl?param=value" access="!isAuthenticated() or hasRole('ROLE_GUEST')" />
<intercept-url pattern="/myUrl" filters="none" />
...
<intercept-url pattern="/**" access="isAuthenticated()" />

如您所见,仅当用户未通过身份验证或使用来宾帐户时,我才需要使用指定的参数访问URL。另外,我为相同的网址添加了一个规则,但没有任何参数,没有过滤器。

据我所知,应该配置Spring安全性在提供较低特定性 之前 提供较高特定性的url
,因为否则,链将首先检测到较通用的规则,而不会继续遵循较高特定性的规则。这就是为什么我希望带有params的url更具体,因此将拒绝对经过身份验证的非guest用户的访问。相反,下面定义的更通用的规则适用。这是输出:

信息[STDOUT] 186879
[http-0.0.0.0-8080-1]调试org.springframework.security.web.FilterChainProxy-
候选人是:“ / myUrl”;模式是/ myUrl; 匹配=真

信息[STDOUT] 186879
[http-0.0.0.0-8080-1]调试org.springframework.security.web.FilterChainProxy-/
myUrl?param = value的过滤器列表为空

我还尝试删除没有参数的url规则。然后,过滤器选择/**模式并要求用户登录,而不是让我的参数带有参数的url起作用。的输出是:

信息[STDOUT] 73066
[http-0.0.0.0-8080-1]调试org.springframework.security.web.FilterChainProxy-
候选人为:“ / myUrl”;模式是/ **; 匹配=真

INFO [STDOUT] 73068
[http-0.0.0.0-8080-1]调试org.springframework.security.web.FilterChainProxy-/
myUrl?param =附加过滤器链中第8位的值;触发过滤器:“ SecurityContextPersistenceFilter”

该应用程序用Java 1.6编写,使用Spring v3.0,并部署在Linux机器上的JBoss
v5.1.0-GA上。我不知道过滤器为何以我描述的方式运行。您的帮助和建议将不胜感激。

编辑:

得出的结论是,我观察到的/myUrl?param=value是从未应用过该过滤器-好像security-
context.xml中的条目被忽略了。这符合我到目前为止观察到的行为。我还尝试了将替换filters="none"access="permitAll",切换为regex(并相应地更改了模式-
例如/myUrl?param=value变为\A/myUrl\?param=value\Z),并且在所有变化中,我得到的行为都是相同的。

编辑2:

这里描述的问题实际上是无效的。原因如下:存在问题的项目由于内部库冲突和不兼容而排除了一些spring软件包,而整个设置却可以正常工作。我从来没有意识到这一点,实际上,这种不纯净的配置使整个问题变得过时了。具体的原因是isAuthenticated()和isAnonymous()方法的实现未按预期工作,因此此处提供的任何建议均无效。


问题答案:

在Spring Security
3.0中,这是(可以理解的)常见的混淆源,因为使用filters="none"会向的模式添加带有空过滤器列表的模式,FilterChainProxy而使用access属性会向的FilterSecurityInterceptor模式添加安全性访问规则以保护URL

匹配过程为:

  1. FilterChainProxy 将请求匹配到过滤器链
  2. 如果过滤器链为非空,则请求将由 FilterSecurityInterceptor

这两个类都维护一个单独的匹配器的有序列表,它们确实按照定义它们的顺序应用,但是您需要了解,实际上在下面配置了两个不直接连接的单独的bean。

在一个简单的名称空间应用程序中,该<http>块将单个过滤器链添加到FilterChainProxywith模式/**filters="none"添加的任何样式都会将空的过滤器链放置在实际链之前。

在Spring Security
3.1中,这种情况已大大改善,因为您可以通过使用单独的<http>块来配置单独的过滤器链,该块可以更直观地映射到Bean级别上实际发生的事情。该请求匹配过程也已经改善了很多,现在使用一个RequestMatcher接口的一切。在组态<http>块时,也可以使用它而不是模式。

因此,您最好的选择可能是升级。然后,您可以实现,以RequestMatcher检查要查找的参数是否存在,例如MyParamRequestMatcher,然后使用:

<http request-matcher-ref="myParamMatcher" security="none" />

<bean:bean id="myParamMatcher" class="MyParamRequestMatcher" />

<http>
    <!-- Define the default filter chain configuration here -->
</http>

请注意,使用URL模式对参数进行匹配通常不太安全,因为通过重新排序URL,添加虚假模式等很容易绕过。您的情况可能还可以,因为带有参数的版本允许不安全的访问,并且您有需要对其他情况进行身份验证的模式。

如果您希望使用3.0,最好的选择是避免使用filters="none“(isAnonymous()代替),并且可能使用正则表达式匹配而不是ant路径,以便您可以更轻松地匹配查询字符串。我再次重复定义此规则的规则几乎可以肯定地绕过这种方式,因此不要依赖它们来提高安全性,并确保默认情况下您是安全的。

更新:

作为对我使用正则表达式匹配和的建议的测试permitAll,如果我像这样修改Spring Security的3.0.x分支中的“教程”示例应用程序,则:

<http use-expressions="true" path-type="regex">
    <intercept-url pattern="\A/secure/extreme/.*\Z" access="hasRole('ROLE_SUPERVISOR')"/>
    <intercept-url pattern="\A/secure/index.jsp\?param=value\Z" access="permitAll" />
    <intercept-url pattern="\A/secure/.*\Z" access="isAuthenticated()" />
    <intercept-url pattern="/.*" access="permitAll" />
    ...
</http>

然后,我得到了预期的行为:

[DEBUG,FilterChainProxy] Candidate is: '/secure/index.jsp?param=value'; pattern is /.*; matched=true
[DEBUG,FilterChainProxy] /secure/index.jsp?param=value at position 1 of 12 in additional filter chain; firing Filter: 'ConcurrentSessionFilter'
...
[DEBUG,FilterChainProxy] /secure/index.jsp?param=value at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
[DEBUG,FilterChainProxy] /secure/index.jsp?param=value at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
[DEBUG,ExpressionBasedFilterInvocationSecurityMetadataSource] Candidate is: '/secure/index.jsp?param=value'; pattern is \A/secure/extreme/.*\Z; matched=false
[DEBUG,ExpressionBasedFilterInvocationSecurityMetadataSource] Candidate is: '/secure/index.jsp?param=value'; pattern is \A/secure/index.jsp\?param=value\Z; matched=true
[DEBUG,FilterSecurityInterceptor] Secure object: FilterInvocation: URL: /secure/index.jsp?param=value; Attributes: [permitAll]

其中显示FilterChainProxy匹配项下的匹配项,.*然后是FilterSecurityInterceptor与参数匹配的确切URL。



 类似资料:
  • 问题内容: 我刚刚从jQuery 1.3.2更新到1.4.3,并且在发出AJAX DELETE请求时看到了一些新行为。由于某种原因,在我的参数中传递的数据没有发送到服务器。例如: 最终向发送了DELETE请求,没有其他数据。但是,这种类型的调用可以很好地传递参数: 有没有其他人看到过类似的行为?有没有理由不再起作用(即:是设计使然,还是错误)?关于如何使其运作的任何建议? 此外,如果有人想知道为什

  • 问题内容: 不知道这是Spring 5.0.3的错误还是新功能可以修复我的问题。 升级后,出现此错误。有趣的是,此错误仅在我的本地计算机上。使用HTTPS协议的测试环境中的相同代码可以正常工作。 继续… 我收到此错误的原因是因为我用于加载结果JSP页面的URL是。评估代码会给我结果。如果我将JSP页面的URL修复为此,则一切正常。 所以我的问题是,我应该/从JSP代码的路径中删除吗,因为这是今后的

  • Amedeus Api调用,我正在通过url编码的“包含=详细票价规则” https://test.api.amadeus.com/v2/shopping/flight-offers/pricing?include=detailed-fare-rules

  • 问题内容: 有没有一种方法可以使用h:outputLink,其他JSF标签或代码来创建html链接,以创建带有请求参数的非面孔请求(HTTP GET)? 例如,我有以下导航规则 在我的页面中,我想输出以下html代码: 我可以在页面中编写html代码,但是我想使用导航规则,以便将所有url定义在一个可配置文件中。 问题答案: 这是一个有趣的想法。我很想知道它在实践中如何成功。 获取导航规则 导航由

  • 返回包含当前URL参数的对象。 通过适当的正则表达式,使用 String.match() 来获得所有的键值对, Array.reduce() 来映射和组合成一个单一的对象。 将 location.search 作为参数传递给当前 url。 const getURLParameters = url => url .match(/([^?=&]+)(=([^&]*))/g) .re

  • 注意:本书中的 Service Mesh 章节已不再维护,请转到 istio-handbook 中浏览。 在上一节安装istio中我们创建BookInfo的示例,熟悉了Istio的基本功能,现在我们再来看一下istio的高级特性——配置请求的路由规则。 使用istio我们可以根据权重和HTTP headers来动态配置请求路由。 基于内容的路由 因为BookInfo示例部署了3个版本的评论微服务,