spring security 4.1.3.RELEASE
intercept-url
request-matcher="mvc"
I try to use spring-security.xml to config my web security with request-matche="mvc"
, but the pattern "/users/{userId:id}" dosen't work.
My config just look like the following code:
<http entry-point-ref="myAuthenticationEntryPoint" auto-config="true" use-expressions="true" create-session="stateless" request-matcher="mvc"
access-decision-manager-ref="myAccessDecisionManager">
<intercept-url pattern="/users/{userId:\\d+}" method="GET" access="@webSecurity.isMe(authentication, #userId) or hasAnyRole('ADMIN')"/>
<intercept-url pattern="/users/management" method="GET" access="hasAnyRole('ADMIN')"/>
</http>
I expecte that the request for /users/12345 will match the pattern /users/{userId:\d+} which will match 12345 to the userId, and the request for /users/management will match the pattern /users/management. However, in fact, the pattern /users/{userId:\d+} dosen't work, it never match the request /users/12345. and if I change the setting to the following code:
<http entry-point-ref="myAuthenticationEntryPoint" auto-config="true" use-expressions="true" create-session="stateless" request-matcher="mvc"
access-decision-manager-ref="myAccessDecisionManager">
<intercept-url pattern="/users/{userId}" method="GET" access="@webSecurity.isMe(authentication, #userId) or hasAnyRole('ADMIN')"/>
<intercept-url pattern="/users/management" method="GET" access="hasAnyRole('ADMIN')"/>
</http>
Remove the :\d+ from /users/{userId:\d+}, it will match the request for /users/12345. But it will match the request for /users/management as well, which makes the value of userId equals to unexpected "management". I have try ant-matcher and regex-matcher, and I can't find the userId in a perfect solution.
I have solved the problem by myself. It's a stupid mistake. To solve the problem, I just need to replace
/users/{userId:\\d+}
with/users/{userId:\d+}
or/users/{userId:[0-9]+}
and use AntPathMatcher instead of using MvcPathMatcher. Configuring the security with spring-security.xml is defferent with using javaConfig or using annotation. In javaConfig or annotation @RequestMapping, the content in""
is String Object, so we need an annother\
to escape the\d+
. But in xml, it's unnecessary. If using\\d+
here, spring security will append it to\\\\d+
, which will never match number type string. I find this solution when I set a breakpoint inorg.springframework.util.AntPathMatcher.matchStrings(String str, Map<String, String> uriTemplateVariables)
and watch the request.