Spring Security请求匹配器不使用正则表达式

时间:2012-11-21 23:52:17

标签: java regex spring-security

使用Spring MVC + Security我有一个业务要求,来自SEC(安全团队)的用户可以完全访问该应用程序,而FRAUD(反欺诈团队)只能访问URL 包含不区分大小写的“ block ”或“ update ”字样。

下面是对 spring-security.xml 中使用的正则表达式的测试(我不是正则表达式专家,欢迎改进=]):

import java.util.Arrays;
import java.util.List;

public class RegexTest {

    public static void main(String[] args) {

        List<String> pathSamples = Arrays.asList(
                "/index",
                "/index.*",
                "/index/",
                "/cellphone/block",
                "/cellphone/block.*",
                "/cellphone/block/",
                "/cellphone/confirmBlock",
                "/cellphone/confirmBlock.*",
                "/cellphone/confirmBlock/",
                "/user/update",
                "/user/update.*",
                "/user/update/",
                "/user/index",
                "/user/index.*",
                "/user/index/",
                "/search",
                "/search.*",
                "/search/",
                "/doSearch",
                "/doSearch.*",
                "/doSearch/");

        for (String pathSample : pathSamples) {
            System.out.println("Path sample: " + pathSample
                    + " - SEC: " + pathSample.matches("^.*$")
                    + " | FRAUD: " + pathSample.matches("^(?!.*(?i)(block|update)).*$"));
        }
    }
}

Bellow,上面的Java类的控制台结果:

Path sample: /index - SEC: true | FRAUD: true
Path sample: /index.* - SEC: true | FRAUD: true
Path sample: /index/ - SEC: true | FRAUD: true
Path sample: /cellphone/block - SEC: true | FRAUD: false
Path sample: /cellphone/block.* - SEC: true | FRAUD: false
Path sample: /cellphone/block/ - SEC: true | FRAUD: false
Path sample: /cellphone/confirmBlock - SEC: true | FRAUD: false
Path sample: /cellphone/confirmBlock.* - SEC: true | FRAUD: false
Path sample: /cellphone/confirmBlock/ - SEC: true | FRAUD: false
Path sample: /user/update - SEC: true | FRAUD: false
Path sample: /user/update.* - SEC: true | FRAUD: false
Path sample: /user/update/ - SEC: true | FRAUD: false
Path sample: /user/index - SEC: true | FRAUD: true
Path sample: /user/index.* - SEC: true | FRAUD: true
Path sample: /user/index/ - SEC: true | FRAUD: true
Path sample: /search - SEC: true | FRAUD: true
Path sample: /search.* - SEC: true | FRAUD: true
Path sample: /search/ - SEC: true | FRAUD: true
Path sample: /doSearch - SEC: true | FRAUD: true
Path sample: /doSearch.* - SEC: true | FRAUD: true
Path sample: /doSearch/ - SEC: true | FRAUD: true

测试

场景1

Bellow, spring-security.xml 的重要部分:

<security:http entry-point-ref="entryPoint" request-matcher="regex">

    <security:intercept-url pattern="^.*$" access="ROLE_SEC" />
    <security:intercept-url pattern="^(?!.*(?i)(block|update)).*$" access="ROLE_FRAUD" />

    <security:access-denied-handler error-page="/access-denied.html" />

    <security:form-login always-use-default-target="false"
        login-processing-url="/doLogin.html"
        authentication-failure-handler-ref="authFailHandler"
        authentication-success-handler-ref="authSuccessHandler" />
    <security:logout logout-url="/logout.html"
        success-handler-ref="logoutSuccessHandler" />
</security:http>

行为:

  • FRAUD组**无法“访问任何页面”
  • SEC小组工作正常

场景2

注意我只更改了 spring-security.xml intercept-url 的顺序:

<security:http entry-point-ref="entryPoint" request-matcher="regex">

    <security:intercept-url pattern="^(?!.*(?i)(block|update)).*$" access="ROLE_FRAUD" />
    <security:intercept-url pattern="^.*$" access="ROLE_SEC" />

    <security:access-denied-handler error-page="/access-denied.html" />

    <security:form-login always-use-default-target="false"
        login-processing-url="/doLogin.html"
        authentication-failure-handler-ref="authFailHandler"
        authentication-success-handler-ref="authSuccessHandler" />
    <security:logout logout-url="/logout.html"
        success-handler-ref="logoutSuccessHandler" />
</security:http>

行为:

  • SEC组**无法“访问任何页面”
  • 欺诈小组工作正常

结论

我做错了什么或者春天安全有错误。

问题已经以非常糟糕的方式解决了,但我需要快速解决。任何人都知道一些技巧,以更好地调试它而不打开框架代码?

干杯,

菲利普

1 个答案:

答案 0 :(得分:3)

第一个配置是错误的,因为通用匹配器是第一个,因此第二个配置将被忽略。第二个配置将从第一个匹配的任何内容中排除SEC角色,因此听起来您想要更像

的内容
<intercept-url pattern="^(?!.*(?i)(block|update)).*$" access="ROLE_FRAUD,ROLE_SEC" />
<intercept-url pattern="^.*$" access="ROLE_SEC" />

在两种模式中都有SEC属性。

如果仍然不是您所需要的,那么请发布相关的调试日志,显示Spring Security选择特定请求的属性(详细记录)并解释它与您的期望有何不同。