Search code examples
javaspring-securitywebsphereappfuse

IBM WebSphere 8.5.5.8(Liberty) + Spring Security 3.1.3.RELEASE


We have a sample web application built on appfuse starter kit version 2.2.1 which uses Spring security 3.1.3.RELEASE. We are going to deploy it on WAS 7 and we are testing it on IBM WebSphere 8.5.5.8(Liberty). Our problem is after successful/failed login request some thing corrupts the servletPath value of the request and sets it to null.

((HttpServletRequest) request).getServletPath()

This is the time when the LocaleFilter tries to do chain.doFilter using /j_security_check value for getServletPath() and we encounter :

Exception thrown by application class 'org.springframework.security.web.util.AntPathRequestMatcher.getRequestPath:116' java.lang.NullPointerException: at org.springframework.security.web.util.AntPathRequestMatcher.getRequestPath(AntPathRequestMatcher.java:116) at org.springframework.security.web.util.AntPathRequestMatcher.matches(AntPathRequestMatcher.java:100) at org.springframework.security.web.DefaultSecurityFilterChain.matches(DefaultSecurityFilterChain.java:42) at org.springframework.security.web.FilterChainProxy.getFilters(FilterChainProxy.java:203) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:176) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259) at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207) at [internal classes] at com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:59) at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207) at [internal classes] at org.tuckey.web.filters.urlrewrite.NormalRewrittenUrl.doRewrite(NormalRewrittenUrl.java:213) at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:171) at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145) at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92) at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:394) at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207) at [internal classes] at ir.dpi.webapp.filter.LocaleFilter.doFilterInternal(LocaleFilter.java:67) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207) at [internal classes] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207) at [internal classes] at com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:129) at com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:77) at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207) at [internal classes]

This is our security.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:beans="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p"
         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
          http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

<http pattern="/images/**" security="none"/>
<http pattern="/styles/**" security="none"/>
<http pattern="/scripts/**" security="none"/>

<http auto-config="false" create-session="always">
    <intercept-url pattern="/app/admin/**" access="ROLE_ADMIN"/>
    <intercept-url pattern="/app/passwordHint*" access="ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER"/>
    <intercept-url pattern="/app/signup*" access="ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER"/>
    <intercept-url pattern="/app/**" access="ROLE_ADMIN,ROLE_USER"/>
    <form-login login-page="/login" authentication-failure-url="/login?error=true" login-processing-url="/j_security_check"/>
    <remember-me user-service-ref="userDao" key="e37f4b31-0c45-11dd-bd0b-0800200c9a66"/>
</http>

<authentication-manager >
    <authentication-provider user-service-ref="userDao" >
        <password-encoder ref="passwordEncoder" >
            <salt-source ref="saltSource" />
        </password-encoder>
    </authentication-provider>
</authentication-manager>

<beans:bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource"
    p:userPropertyToUse="username"/>


<global-method-security>
    <protect-pointcut expression="execution(* *..service.UserManager.getUsers(..))" access="ROLE_ADMIN"/>
    <protect-pointcut expression="execution(* *..service.UserManager.removeUser(..))" access="ROLE_ADMIN"/>
</global-method-security>
</beans:beans>

Any help would be appreciated.


Solution

  • I have found the solution using this code ranch topic. AppFuse uses different Filters(javax.servlet) and the Wrapping mechanism of IBM WebSphere is sensitive to the session creation precedence. So I have moved Spring securityFilter mapping upward in the web.xml file.

         <filter-mapping>
            <filter-name>securityFilter</filter-name>
            <url-pattern>/*</url-pattern>
            <dispatcher>REQUEST</dispatcher>
            <dispatcher>FORWARD</dispatcher>
            <dispatcher>INCLUDE</dispatcher>
         </filter-mapping>
    
         <filter-mapping>
            <filter-name>sitemesh</filter-name>
            <url-pattern>/*</url-pattern>
            <dispatcher>REQUEST</dispatcher>
            <dispatcher>FORWARD</dispatcher>
         </filter-mapping>
    
         <filter-mapping>
            <filter-name>encodingFilter</filter-name>
            <url-pattern>/*</url-pattern>
         </filter-mapping>
         ...
    

    Now the Login process is done completely.

    Please note that it is vital to set these settings in the Liberty server.xml:

    <httpSession cookieName="MY_LIBERTY_COOKIE" />
    <basicRegistry />
    

    The equivalent settings in the IBM WebSphere Application Server(WAS Full) is set in:

    Session management -> General Properties -> Enable cookies

    Also in WAS version 7 (may apply to other versions) it is required to use:

    <http auto-config="false" disable-url-rewriting="true" create-session="always">
    

    in the spring security.xml file.