Announcement Announcement Module
Collapse
No announcement yet.
Spring Security 3.0.6: not directed to logout-success-url Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring Security 3.0.6: not directed to logout-success-url

    Please help, I have a problem here. This is my security configuration:
    Code:
    <http auto-config="true" use-expressions="true">
        <form-login login-page="/login" default-target-url="/employee"
                    login-processing-url="/j_spring_security_check"
                    authentication-failure-url="/login?login_error=true"/>
        <logout logout-url="/j_spring_security_logout" logout-success-url="/login"/>
        <intercept-url pattern="/just_logout" filters="none"/>
        <intercept-url pattern="/login*" filters="none"/>
        <intercept-url pattern="/**" access="hasRole('ROLE_EMPLOYEE')"/>
    </http>
    
    <authentication-manager>
        <authentication-provider>
            <user-service id="userService">
                <user name="a" password="a" authorities="ROLE_EMPLOYEE"/>
                <user name="b" password="b" authorities="ROLE_EMPLOYEE,ROLE_ADMIN"/>
            </user-service>
        </authentication-provider>
    </authentication-manager>
    This is my logout url:
    Code:
    <%@ taglib prefix="s" uri="http://www.springframework.org/tags" %>
    <s:url value="/j_spring_security_logout" var="logoutUrl"/>
    
    <a href="${logoutUrl}">Logout</a>
    This is the debug logging messages when the logout link is clicked:
    Code:
    19:14:33 DEBUG FilterChainProxy:194 - Converted URL to lowercase, from: '/j_spring_security_logout'; to: '/j_spring_security_logout'
    19:14:33 DEBUG FilterChainProxy:201 - Candidate is: '/j_spring_security_logout'; pattern is /just_logout; matched=false
    19:14:33 DEBUG FilterChainProxy:194 - Converted URL to lowercase, from: '/j_spring_security_logout'; to: '/j_spring_security_logout'
    19:14:33 DEBUG FilterChainProxy:201 - Candidate is: '/j_spring_security_logout'; pattern is /login*; matched=false
    19:14:33 DEBUG FilterChainProxy:194 - Converted URL to lowercase, from: '/j_spring_security_logout'; to: '/j_spring_security_logout'
    19:14:33 DEBUG FilterChainProxy:201 - Candidate is: '/j_spring_security_logout'; pattern is /**; matched=true
    19:14:33 DEBUG FilterChainProxy$VirtualFilterChain:376 - /j_spring_security_logout at position 1 of 10 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
    19:14:33 DEBUG HttpSessionSecurityContextRepository:166 - Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: '[email protected]71221: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@b3571221: Principal: org.springframework.security.core.userdetails.User@61: Username: a; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_EMPLOYEE; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@59b2: RemoteIpAddress: ::1; SessionId: 65E44E00E3F23B265FDC363BF2EBFCF0; Granted Authorities: ROLE_EMPLOYEE'
    19:14:33 DEBUG FilterChainProxy$VirtualFilterChain:376 - /j_spring_security_logout at position 2 of 10 in additional filter chain; firing Filter: 'LogoutFilter'
    19:14:33 DEBUG LogoutFilter:93 - Logging out user 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@b3571221: Principal: org.springframework.security.core.userdetails.User@61: Username: a; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_EMPLOYEE; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@59b2: RemoteIpAddress: ::1; SessionId: 65E44E00E3F23B265FDC363BF2EBFCF0; Granted Authorities: ROLE_EMPLOYEE' and transferring to logout destination
    19:14:33 DEBUG HttpSessionSecurityContextRepository$SaveToSessionResponseWrapper:338 - SecurityContext is empty or anonymous - context will not be stored in HttpSession. 
    19:14:33 DEBUG SecurityContextPersistenceFilter:89 - SecurityContextHolder now cleared, as request processing completed
    And this is what can be seen in the browser (the url at that time is http://localhost:9090/springmvc/j_sp...urity_logout):
    Code:
    HTTP Status 500 -
    type Exception report
    
    message
    
    description The server encountered an internal error () that prevented it from fulfilling this request.
    
    exception
    
    java.lang.NullPointerException
    	java.util.Hashtable.get(Hashtable.java:334)
    	org.apache.tomcat.util.http.Parameters.getParameterValues(Parameters.java:116)
    	org.apache.tomcat.util.http.Parameters.getParameter(Parameters.java:127)
    	org.apache.catalina.connector.Request.getParameter(Request.java:1133)
    	org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:384)
    	javax.servlet.ServletRequestWrapper.getParameter(ServletRequestWrapper.java:140)
    	org.springframework.security.web.authentication.AbstractAuthenticationTargetUrlRequestHandler.determineTargetUrl(AbstractAuthenticationTargetUrlRequestHandler.java:86)
    	org.springframework.security.web.authentication.AbstractAuthenticationTargetUrlRequestHandler.handle(AbstractAuthenticationTargetUrlRequestHandler.java:67)
    	org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler.onLogoutSuccess(SimpleUrlLogoutSuccessHandler.java:28)
    	org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:100)
    	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
    	org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
    	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
    	org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:168)
    	org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
    	org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
    
    note The full stack trace of the root cause is available in the Apache Tomcat/7.0.20 logs.
    What do I miss here? Please help. Thank you.

  • #2
    It appears that a null value is being passed into HttpServletRequest.getParameter when looking for the targetUrlParameter. However, the configuration you have posted should not do that. Are you changing the targetUrlParameter anywhere else? Did you create your own HttpServletRequestWrapper that might be doing this? Are you using any Filter's that might be wrapping the request for you? What does your full web.xml look like?

    Comment


    • #3
      Spring Security 3.0.6: not directed to logout-success-url

      Originally posted by rwinch View Post
      It appears that a null value is being passed into HttpServletRequest.getParameter when looking for the targetUrlParameter. However, the configuration you have posted should not do that. Are you changing the targetUrlParameter anywhere else? Did you create your own HttpServletRequestWrapper that might be doing this? Are you using any Filter's that might be wrapping the request for you? What does your full web.xml look like?
      Hi,
      I've had exactly the same problem, but if I downgrade the spring version to 3.0.5, it works as expected.
      My configuration was the same as the one above.

      Ivan

      Comment


      • #4
        Hello,

        I'm having the exact same problem, and I don't remember changing anything on my security configuration or web.xml configuration.

        Here is my web.xml:
        Code:
        <?xml version="1.0" encoding="UTF-8"?>
        <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
            <context-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>/WEB-INF/classes/applicationContext.xml</param-value>
            </context-param>
            <context-param>
                <param-name>log4jConfigLocation</param-name>
                <param-value>/WEB-INF/classes/log4j.properties</param-value>
            </context-param>
            <context-param>
                <param-name>log4jRefreshInterval</param-name>
                <param-value>1000</param-value>
            </context-param>
        
            <filter>
                <filter-name>springSecurityFilterChain</filter-name>
                <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
            </filter>
            <filter>
                <filter-name>hiddenHttpMethodFilter</filter-name>
                <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
            </filter>
        
            <filter-mapping>
              <filter-name>springSecurityFilterChain</filter-name>
              <url-pattern>/*</url-pattern>
            </filter-mapping>
            <filter-mapping>
                <filter-name>hiddenHttpMethodFilter</filter-name>
                <url-pattern>/*</url-pattern>
            </filter-mapping>
        
            <listener>
                <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
            </listener>
            <listener>
                <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
            </listener>
        
            <servlet>
                <servlet-name>dispatcher</servlet-name>
                <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
                <init-param>
                    <param-name>contextConfigLocation</param-name>
                    <param-value>/WEB-INF/classes/applicationContext.xml</param-value>
                </init-param>
                <load-on-startup>2</load-on-startup>
            </servlet>
        
            <servlet-mapping>
                <servlet-name>default</servlet-name>
                <url-pattern>/static/*</url-pattern>
            </servlet-mapping>
            <servlet-mapping>
                <servlet-name>dispatcher</servlet-name>
                <url-pattern>/</url-pattern>
            </servlet-mapping>
        
            <session-config>
                <session-timeout>
                    30
                </session-timeout>
            </session-config>
            <welcome-file-list>
                <welcome-file>index.jsp</welcome-file>
            </welcome-file-list>
        </web-app>
        My security configuration is very similar to the person above, I just don't set a logout-success-url. I've done it to see if it was a problem with that, but didn't solve the problem.

        I debugged into org.springframework.security.web.authentication.Ab stractAuthenticationTargetUrlRequestHandler.determ ineTargetUrl(AbstractAuthenticationTargetUrlReques tHandler.java:86) and saw that the request.parameterMap is empty. And also the targetUrlParameter from the LogoutHandler is null.

        I noticed that SimpleUrlLogoutSuccessHandler set targetUrlParameter to null
        Code:
        public class SimpleUrlLogoutSuccessHandler extends AbstractAuthenticationTargetUrlRequestHandler
                implements LogoutSuccessHandler {
        
            public SimpleUrlLogoutSuccessHandler() {
                super.setTargetUrlParameter(null);
            }
        
            public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
                    throws IOException, ServletException {
                super.handle(request, response, authentication);
            }
        
        }
        I found it strange and created a custom LogoutSuccessHandler for the sake of testing.
        Code:
        public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
        
            public CustomLogoutSuccessHandler() {
                super.setTargetUrlParameter("nothing");
            }
           
        }
        And... it worked. I looks like SimpleUrlLogoutSuccessHandler changed from 3.0.5 and added this new constructor.
        Hope this helps something.

        It is also funny that if you don't initialize the targetUrlParameter with a String, the AbstractAuthenticationTargetUrlRequestHandler also sets it to null.
        Code:
        public void setTargetUrlParameter(String targetUrlParameter) {
            if (!StringUtils.hasText(targetUrlParameter)) {
                targetUrlParameter = null;
            }
            this.targetUrlParameter = targetUrlParameter;
        }
        And it also changed from 3.0.5:
        Code:
        public void setTargetUrlParameter(String targetUrlParameter) {
            Assert.hasText("targetUrlParameter canot be null or empty");
            this.targetUrlParameter = targetUrlParameter;
        }
        Is this an expected behavior? Should there be any change in the configuration for logout to work this way, with targetUrlParameter == null? Or is this a bug?

        Thanks

        Comment


        • #5
          I've got the same problem

          I've got exactly the same problem. I moved from 3.0.5 to 3.0.6 with no changes on my applicationContext-Security.xml file, and when a user logs out, the same error ocurrs.

          Comment


          • #6
            Wow! Thank you very much. You're a real life saver
            Originally posted by orapouso View Post
            I noticed that SimpleUrlLogoutSuccessHandler set targetUrlParameter to null
            I also came there and intended to write a MySimpleUrlLogoutSuccessHandler but ... how did you tell Spring to use your CustomLogoutSuccessHandler? If you told it by saying
            Code:
            <logout success-handler-ref="customLogoutSuccessHandler"/>
            then what was the logout url in that case (you cannot specify both logout-url and success-handler-ref, I did that and spring threw an exception)?

            I also created an app with spring roo 1.1.5 and changed the pom.xml so that security 3.0.6 was used. There was some error inside when I tried to logout, but the generated app swallowed the exceptions so I didn't see anything. Apparently, spring security 3.0.6 has some problem.
            Last edited by dxxvi; Sep 2nd, 2011, 06:08 AM.

            Comment


            • #7
              Originally posted by dxxvi View Post
              I also came there and intended to write a MySimpleUrlLogoutSuccessHandler but ... how did you tell Spring to use your CustomLogoutSuccessHandler? If you told it by saying
              Code:
              <logout success-handler-ref="customLogoutSuccessHandler"/>
              then what was the logout url in that case (you cannot specify both logout-url and success-handler-ref, I did that and spring threw an exception)?
              Hi,

              Well, here is my logout element and it works perfectly:
              Code:
              <sec:logout logout-url="/logout" success-handler-ref="logoutSuccessHandler" />
              It accepts both logout-url and success-handler-ref. This logout-url is probably configured in the LogoutFilter rather than in the handler, so it shouldn't be a problem setting both. The handler goes after the filter says it is a successful logout, and the handler is not aware of the logoutUrl. I think you should investigate it further, or try something different. If you could output the error, maybe I could try to help you, but since I don't get the error, I don't know.

              Cheers

              Comment


              • #8
                I found a JIRA ticket for this: https://jira.springsource.org/browse/SEC-1803

                And another possible solution:
                Code:
                <bean class="org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler">
                    <property name="targetUrlParameter">
                        <util:constant static-field="org.springframework.security.web.authentication.AbstractAuthenticationTargetUrlRequestHandler.DEFAULT_TARGET_PARAMETER"/>
                    </property>
                </bean>
                This appears easier than implementing a new class just to overcome the bug. But then you have to use the "util" namespace.

                Cheers

                Comment


                • #9
                  Hi,
                  I tired to define the SimpleUrlLogoutSuccessHandler explicitly like described above, but this had no effect at all. The NPE remains the same.

                  Any ideas, what went wrong?

                  I also tried to update all Spring dependencies to 3.0.7.RELEASE or even 3.1.0.RELEASE for testing. But then, with both versions, most of my tests fail due to several ClassNotFoundExceptions within Spring.

                  Regards,
                  michael

                  Comment


                  • #10
                    Updating to 3.0.7.RELEASE should fix your problem. Make sure that you have updated all of your Spring Security dependencies to 3.0.7.RELEASE. If this does not work, please post the complete stack trace you get (using the code tags). If it has to do with ClassNotFoundExceptions please post a listing of the dependencies and versions that are in the WEB-INF/lib of your war.

                    Comment

                    Working...
                    X