Search code examples
javaurl-rewritingspring-securityapache2mod-jk

Apache/mod_jk with Spring Security


I am having some issues when using mod_jk with Spring Security that has worked on previous projects but I can't seem to make it work now.

I've got a fairly typical situation using JBoss (but could as easily be Tomcat) when my web app is located at http://hostname/myapp and I want this to be hidden from the browser such that all accesses will be http://hostname

In Apache I've got a couple of rules :-

# Remove double "myapp" in url
RewriteRule ^/myapp/(.*) /$1

# Check to see if content can be served locally - rewrite back if not
RewriteCond /dir/to/static/content -f
RewriteRule ^/(.*) /myapp/$1 [PT]

JkMount /myapp/* loadbalancer

I've stripped back my Spring Security to be as simple as possible :

<security:http auto-config="true">
<security:intercept-url pattern="/**" access="ROLE_USER" />
</security:http>

In my web.xml

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
 </filter-mapping>

The issue is that without Spring security (ie. remove the springSecurityFilterChain) this works fine, but with it included I get issues like

Reason: Authentication method not supported: GET

when I try to log in.

My questions are :

  1. Is this a Spring Security issue needing configuration, or is my Apache not correct?
  2. Has anyone got a working config that they can share with me!

I've been struggling with this for several hours, reading lots of posts but I've not managed to get it working.


Solution

  • To answer my own question to possibly help other people in the future. I had to switch to mod_proxy as opposed to mod_jk.

    My setup looks like this

    <Proxy>
       Order deny,allow
       Allow from all
    </Proxy>
    
    RewriteCond /dir/to/static/content/%{REQUEST_FILENAME} !-f
    RewriteRule ^/(.*) ajp://127.0.0.1:8009/myapp/$1 [P]
    ProxyPassReverse /  http://myurl/myapp/
    ProxyPassReverseCookiePath /myapp /
    

    My spring security file

    <security:http auto-config="false" use-expressions="true" disable-url-rewriting="true">
       <security:intercept-url pattern="/app/login" access="permitAll" />
       <security:intercept-url pattern="/app/**" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')" />
       <security:form-login
        login-page="/app/login"
        authentication-failure-url="/app/login?f=1"
        default-target-url="/app/map"/>
       <security:logout logout-url="/app/logout"/>
     </security:http>
    

    I think the key is the ProxyPassReverseCookiePath statement.