Spring Security: How to force https with flag?
With Spring security I configure the parts of my web app that need to be secured by https with security:intercept-url
tag.
For example:
<security:intercept-url pattern="/**/*secure*" requires-channel="https"/>
<security:intercept-url pattern="/**" requires-channel="http" />
T开发者_开发技巧his way all requests with "secure" in the file name or directories containing "secure" on the lowest level get https, the rest will get http.
Is there a way to use a flag to make Spring force https? I could not get anything to work that takes stuff after the "?" of an url.
http://domain/abc?secure=true
=> httpshttp://domain/abc => http
Spring would then redirect transparently every request going to http://domain/abc?secure=true
to https://domain/abc?secure=true
.
Is there a way to achieve that? The first pattern in the example achieves the result for a "secure" occuring before the "?", but I am looking for a solution/pattern to have a flag after the "?" only.
To make Spring consider fragments after the "?" in urls, the stripQueryStringFromUrls has to be set to false.
Here is a solutation I found in the Spring forum: When this BeanPostProcessor is loaded, the property will be set.
public class BeanPostProcessorImpl implements BeanPostProcessor
{
final static private Logger log = Logger.getLogger(BeanPostProcessorImpl.class);
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException
{
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException
{
if (bean instanceof DefaultFilterInvocationSecurityMetadataSource)
{
log.info("********* Post-processing " + beanName);
((DefaultFilterInvocationSecurityMetadataSource) bean).setStripQueryStringFromUrls(false);
}
return bean;
}
}
This way pattern
<security:intercept-url pattern="/**/*?secure=true*" requires-channel="https"/>
finally works.
As far as I can tell you want to have a URL param which to tell spring to redirect you to an https channel.
So did you try:
<security:intercept-url pattern="/**/*?secure*" requires-channel="https"/>
or if that doesn't work try an escaped '?' :
<security:intercept-url pattern="/**/*\?secure*" requires-channel="https"/>
I just had a look at the source for the FilterChainProxy
(in 3.0.5.RELEASE) and it uses regular expressions to match the patterns. So you can have a look at:
org.springframework.security.web.util.RegexUrlPathMatcher#pathMatchesUrl(Object compiledPath, String url)
or
org.springframework.security.web.FilterChainProxy#getFilters(String url)
to see exactly what pattern you need.
So even if spring currently doesn't support the '?' sign you can extend your own UrlPathMatcher
and inject it into the FilterChainProxy
.
精彩评论