Is there a way, using Spring Security (v 3.1.x), to programmatically get authorization rules for a certain URL?
I mean... suppose I set:
<security:intercept-url pattern="/**" access="isAuthenticated()" />
in my configuration.
In the controller handling /internal/**
paths I'd like to know if I need authentication to access a certain path. A method like this:
boolean isAuthenticationRequired(String ulr);
could be useful.
Can I get this information via SecurityContextHolder
?
UPDATE Searching around it seems that the key could be SecurityMetadataSource
...
If you're using schema-based configuration I think this is the only (and ugly) way to get to the SecurityMetadataSource and the rules:
@Autowired
private ApplicationContext applicationContext;
public void someMethod(){
FilterSecurityInterceptor fsi = applicationContext.getBean(org.springframework.security.web.access.intercept.FilterSecurityInterceptor.class);
FilterInvocationSecurityMetadataSource sms = fsi.getSecurityMetadataSource();
try {
Field field = sms.getClass().getDeclaredField("requestMap");
field.setAccessible(true);
Map<RequestMatcher, Collection<ConfigAttribute>> requestMap = (Map<RequestMatcher, Collection<ConfigAttribute>>)field.get(sms);
Set<Entry<RequestMatcher, Collection<ConfigAttribute>>> entrySet = requestMap.entrySet();
for (Entry<RequestMatcher, Collection<ConfigAttribute>> entry : entrySet) {
AntPathRequestMatcher path = (AntPathRequestMatcher)entry.getKey();
System.out.println(path.getPattern());
//prints sthg like /action/index
Collection<ConfigAttribute> roles = entry.getValue();
System.out.println(roles);
//[ROLE_USER,ROLE_ADMIN]
}
} catch (Exception e) {
//TODO
e.printStackTrace();
}
}
Using this you can easily program a utility service to check a URL.
The alternative is cleaner but in the end more verbose: if you're not using schema-based configuration, you can access more easily the bean containing the mapping (interceptedUrls):
<bean id="fsi" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
<property name="securityMetadataSource" ref="interceptedUrls"/>
</bean>
<sec:filter-invocation-definition-source id="interceptedUrls">
<sec:intercept-url pattern="/action/login" access="ROLE_ANONYMOUS"/>
<sec:intercept-url pattern="/action/passwordReset" access="ROLE_ANONYMOUS"/>
<sec:intercept-url pattern="/action/index" access="ROLE_ADMIN"/>
...
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With