![](/img/trans.png)
[英]Spring Security intercept url appears to be skipped/ignored
[英]Spring Security - Url with request parameters rules ignored
我有一個使用spring安全性的Web應用程序。 它使用<intercept-url ../>
元素來描述不同URL的訪問過濾器。 默認情況下,這不會考慮URL的請求參數。 我需要根據請求參數設置url的自定義安全規則。 所以我做了以下事情:
1)我創建了一個bean后處理器類,它將為spring安全機制啟用請求參數選項:
<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
}
這應該設置spring安全元數據源以考慮請求參數。 我已經調試了上面的代碼,並且正在設置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。 另外,我為同一個網址添加了規則,但沒有任何沒有過濾器的參數。
據我所知,春季安全應配置提供更具體的網址前不太確切的,因為否則鏈將首先檢測更一般的規則,不會繼續更具體的了。 這就是為什么我希望帶有params的url更具體,因此被拒絕訪問經過身份驗證的非來賓用戶。 相反,下面定義的更一般的規則適用。 這是輸出:
INFO [STDOUT] 186879 [http-0.0.0.0-8080-1] DEBUG org.springframework.security.web.FilterChainProxy - 候選人是:'/ myUrl'; pattern是/ myUrl; 匹配=真
INFO [STDOUT] 186879 [http-0.0.0.0-8080-1] DEBUG org.springframework.security.web.FilterChainProxy - / myUrl?param = value有一個空的過濾列表
我還試圖刪除url的規則,沒有params。 然后,過濾器選擇/**
模式並要求用戶登錄,而不是使用params工作的url規則。 輸出是:
INFO [STDOUT] 73066 [http-0.0.0.0-8080-1] DEBUG org.springframework.security.web.FilterChainProxy - 候選人是:'/ myUrl'; 模式是/ **; 匹配=真
INFO [STDOUT] 73068 [http-0.0.0.0-8080-1] DEBUG org.springframework.security.web.FilterChainProxy - / myUrl?param =附加過濾器鏈中第1位的值為8; 觸發過濾器:'SecurityContextPersistenceFilter'
該應用程序使用Java 1.6編寫,使用Spring v3.0,並在Linux機器上部署在JBoss v5.1.0-GA上。 我沒有線索為什么過濾器按照我描述的方式運行。 非常感謝您的幫助和建議。
編輯:
作為結論,我觀察到從未應用/myUrl?param=value
過濾器 - 就好像忽略了security-context.xml中的條目一樣。 這符合我迄今為止觀察到的行為。 我也嘗試用access="permitAll"
替換filters="none"
,切換到正則表達式(並相應地更改模式 - 例如/myUrl?param=value
變為\\A/myUrl\\?param=value\\Z
)變化我得到的行為是一樣的。
編輯2:
這里描述的問題實際上是無效的。 原因如下:出現問題的項目由於內部庫沖突和不兼容性而排除了一些彈簧包,而整個設置在某種程度上起作用。 我從來沒有意識到這一點,實際上這種不合適的配置使整個問題過時了。 具體原因是isAuthenticated()和isAnonymous()方法的實現沒有按預期工作,因此這里提供的任何建議都不起作用。
在Spring Security 3.0中,這是(可以理解)混淆的一個常見原因,因為filters="none"
的使用會向FilterChainProxy
添加一個帶有空過濾器列表的模式,而使用access
屬性會添加一個安全訪問規則FilterSecurityInterceptor
,用於保護URL。
匹配過程是:
FilterChainProxy
將請求與過濾器鏈匹配 FilterSecurityInterceptor
將檢查請求 這兩個類都維護一個單獨的有序匹配列表,它們按照您定義它們的順序應用它們,但是您需要了解下面實際上有兩個單獨的bean正在配置而沒有直接連接。
在一個簡單的命名空間應用程序中, <http>
塊正在使用pattern /**
向FilterChainProxy
添加單個過濾器鏈。 您添加的任何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。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.