Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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" />    

This 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 => https
  • http://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.

like image 581
Ansgar Avatar asked Jun 22 '11 14:06

Ansgar


2 Answers

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.

like image 69
Ansgar Avatar answered Nov 09 '22 20:11

Ansgar


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.

like image 32
Simeon Avatar answered Nov 09 '22 19:11

Simeon