Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rewrite spring-security redirect URLs

I'm trying to get Tuckey UrlRewriteFilter to tidy up URLs for my webapp. One problem I've got is that when spring-security notices that an anonymous user is trying to access a protected resource it redirects to a URL which includes the servlet path.

What I'd like is, by example:

> GET http://localhost:8080/my-context/protected-resource
< Location: http://localhost:8080/my-context/login

What I currently get is:

> GET http://localhost:8080/my-context/protected-resource
< Location: http://localhost:8080/my-context/-/login

Relevant documents I've found so far:

DefaultRedirectStrategy, which does the actual redirect in question: http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/web/DefaultRedirectStrategy.html. It has a contextRelative property which is tempting but I don't think is going to cut it, if I can even find a way of configuring it.

A blog post that helped get me this far: http://nonrepeatable.blogspot.com/2009/11/using-spring-security-with-tuckey.html

What I'd like to know is:

  1. Can/should I convince Tuckey to rewrite the Location header. <outbound-rule> doesn't seem to help any here.
  2. Can/should I somehow tweak the SS config to emit the rewritten URL. I don't think this is quite as tidy, as it'd break if rewrite was disabled.

web.xml looks like

<filter>
    <filter-name>UrlRewriteFilter</filter-name>
    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
    <init-param>
        <param-name>LogLevel</param-name>
        <param-value>log4j</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

<servlet>
    <servlet-name>my-servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>psms</servlet-name>
    <url-pattern>/-/*</url-pattern>
</servlet-mapping>

urlrewrite.xml looks like:

<urlrewrite>
    <rule>
        <from>^/(.*)$</from>
        <to>/-/$1</to>
    </rule>
</urlrewrite>

applicationContent-security.xml looks like:

<http auto-config="true">
    <!-- allow GET requests to /login without authentication -->
    <intercept-url pattern="/-/login" method="GET" filters="none"/>

    <intercept-url pattern="/-/admin/**" access="ROLE_ADMIN"/>
    <intercept-url pattern="/-/**" access="ROLE_USER"/>

    <form-login login-page="/-/login"
                login-processing-url="/-/login.do"
                authentication-failure-url="/-/login?login_error"
                default-target-url="/-/index"
                always-use-default-target="true"/>

    <logout logout-url="/-/logout"
            logout-success-url="/-/login"/>

    <access-denied-handler error-page="/-/access-denied"/>
</http>
like image 202
ptomli Avatar asked Nov 19 '09 10:11

ptomli


3 Answers

I looked into this issue for our project last year and at that time the problem was that Tucky wasn't cooperating with response.encodeRedirectUrl() to rewrite redirect URLs. I contacted them but I haven't followed up on this.

My solution was to allow the messy URL to go back to the client but then clean it up with a Tucky redirect rule (a second redirect).

So add another rule that matches your ugly URL from the security redirect and issue your own redirect to the clean URL:

<rule>
    <from>^/whatever/ugly.*$</from>
    <to type="redirect">/login</to>
</rule>

Yes, it involves two redirects, but the client will never see it... which is probably the point.

like image 196
Pat Niemeyer Avatar answered Sep 29 '22 00:09

Pat Niemeyer


I ran into the same problem, but it seems fixed in version 3.2.0 of Tuckey. i.e. the response.encodeRedirectUrl() is now wrapped by Tuckeys UrlRewriteWrappedResponse where the outbound rule execution takes place.

like image 35
Bas Avatar answered Sep 28 '22 23:09

Bas


Spring security is doing the redirect with an absolute URL like http://example.org/-/login

Try to use an outbound-rule without the ^ start of string marker to match the absolute url generated by spring.

<outbound-rule>
    <from>/-/login(.*)$</from>
    <to>/login$1</to>
</outbound-rule>    
like image 27
Serxipc Avatar answered Sep 29 '22 00:09

Serxipc