Spring security request matcher is not working with regex
Posted
by
Felipe Cardoso Martins
on Stack Overflow
See other posts from Stack Overflow
or by Felipe Cardoso Martins
Published on 2012-11-21T23:52:16Z
Indexed on
2012/11/22
22:59 UTC
Read the original article
Hit count: 581
Using Spring MVC + Security I have a business requirement that the users from SEC (Security team) has full access to the application and FRAUD (Anti-fraud team) has only access to the pages that URL not contains the words "block" or "update" with case insensitive.
Bellow, all spring dependencies:
$ mvn dependency:tree | grep spring
[INFO] +- org.springframework:spring-webmvc:jar:3.1.2.RELEASE:compile
[INFO] | +- org.springframework:spring-asm:jar:3.1.2.RELEASE:compile
[INFO] | +- org.springframework:spring-beans:jar:3.1.2.RELEASE:compile
[INFO] | +- org.springframework:spring-context:jar:3.1.2.RELEASE:compile
[INFO] | +- org.springframework:spring-context-support:jar:3.1.2.RELEASE:compile
[INFO] | \- org.springframework:spring-expression:jar:3.1.2.RELEASE:compile
[INFO] +- org.springframework:spring-core:jar:3.1.2.RELEASE:compile
[INFO] +- org.springframework:spring-web:jar:3.1.2.RELEASE:compile
[INFO] +- org.springframework.security:spring-security-core:jar:3.1.2.RELEASE:compile
[INFO] | \- org.springframework:spring-aop:jar:3.0.7.RELEASE:compile
[INFO] +- org.springframework.security:spring-security-web:jar:3.1.2.RELEASE:compile
[INFO] | +- org.springframework:spring-jdbc:jar:3.0.7.RELEASE:compile
[INFO] | \- org.springframework:spring-tx:jar:3.0.7.RELEASE:compile
[INFO] +- org.springframework.security:spring-security-config:jar:3.1.2.RELEASE:compile
[INFO] +- org.springframework.security:spring-security-acl:jar:3.1.2.RELEASE:compile
Bellow, some examples of mapped URL path from spring log:
Mapped URL path [/index] onto handler 'homeController'
Mapped URL path [/index.*] onto handler 'homeController'
Mapped URL path [/index/] onto handler 'homeController'
Mapped URL path [/cellphone/block] onto handler 'cellphoneController'
Mapped URL path [/cellphone/block.*] onto handler 'cellphoneController'
Mapped URL path [/cellphone/block/] onto handler 'cellphoneController'
Mapped URL path [/cellphone/confirmBlock] onto handler 'cellphoneController'
Mapped URL path [/cellphone/confirmBlock.*] onto handler 'cellphoneController'
Mapped URL path [/cellphone/confirmBlock/] onto handler 'cellphoneController'
Mapped URL path [/user/update] onto handler 'userController'
Mapped URL path [/user/update.*] onto handler 'userController'
Mapped URL path [/user/update/] onto handler 'userController'
Mapped URL path [/user/index] onto handler 'userController'
Mapped URL path [/user/index.*] onto handler 'userController'
Mapped URL path [/user/index/] onto handler 'userController'
Mapped URL path [/search] onto handler 'searchController'
Mapped URL path [/search.*] onto handler 'searchController'
Mapped URL path [/search/] onto handler 'searchController'
Mapped URL path [/doSearch] onto handler 'searchController'
Mapped URL path [/doSearch.*] onto handler 'searchController'
Mapped URL path [/doSearch/] onto handler 'searchController'
Bellow, a test of the regular expressions used in spring-security.xml (I'm not a regex speciality, improvements are welcome =]):
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, the console result of Java class above:
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
Tests
Scenario 1
Bellow, the important part of 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>
Behaviour:
- FRAUD group **can't" access any page
- SEC group works fine
Scenario 2
NOTE that I only changed the order of intercept-url in spring-security.xml bellow:
<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>
Behaviour:
- SEC group **can't" access any page
- FRAUD group works fine
Conclusion
I did something wrong or spring-security have a bug.
The problem already was solved in a very bad way, but I need to fix it quickly. Anyone knows some tricks to debug better it without open the frameworks code?
Cheers,
Felipe
© Stack Overflow or respective owner