Uploaded image for project: 'Crowd Data Center'
  1. Crowd Data Center
  2. CWD-4109

SSO Cookie Expires at Session End Instead of Configured Timeout

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Low Low
    • None
    • 2.7.2
    • SSO

      The SSO cookie set by Confluence/Crowd ("crowd.token_key") is set to expire at session end, after the browser is quit.

      This disables any and all "Remember me" checkboxes the users check in Confluence and people have to re-login after each browser start.

      The token stays in the database, yes, but the cookie set by either crowd or confluence and jira (since they all use the same lib) has a expiry time of "session", meaning the cookie with the token inside is gone as soon as the user closes the browser. This obviously happens in any browser.

      The steps to reproduce/see this issue is:
      a) Crowd 2.7.2+
      b) Confluence using a Crowd dictionary + the SSO authenticator in seraph-config.xml is configured properly:

      <authenticator class="com.atlassian.confluence.user.ConfluenceCrowdSSOAuthenticator"/>

      Any cookie (by default, it's named "crowd.token_key") set when logging in to a) or b) will not have a MaxAge= parameter set. The code to see this is in atlassian-crowd/components/crowd-integration-client-common/*/CrowdHttpTokenHelperImpl.java in line 188/buildCookie(), which generates a standard servlet Cookie that has no MaxAge value set.

      As said, the net effect is that SSO sessions are "lost" to the browser as soon as the user restarts his browser, and he has to re-login even if the server side session still persists.

          Form Name

            [CWD-4109] SSO Cookie Expires at Session End Instead of Configured Timeout

            Warren Spencer added a comment - - edited

            Hello Stephen,

            Sorry - I didn't get a notification for your response; I don't know whether it's worth your effort to push it through; it may however not be wise to rely on browser-specific behaviour (which can be disabled per-user) either.

             

            Ultimately that's your guys' call - I can say that this bug caused me significant grief (and if I wasn't able to come up with the nginx hackaround above we may not have ended up adopting the Atlassian suite at all).  Especially since my workplace (and many other government teams & enterprises) will be using IE for years to come!

             

            Cheers,

            Warren

             

            Edit: typo

            Warren Spencer added a comment - - edited Hello Stephen, Sorry - I didn't get a notification for your response; I don't know whether it's worth your effort to push it through; it may however not be wise to rely on browser-specific behaviour (which can be disabled per-user) either.   Ultimately that's your guys' call - I can say that this bug caused me significant grief (and if I wasn't able to come up with the nginx hackaround above we may not have ended up adopting the Atlassian suite at all).  Especially since my workplace (and many other government teams & enterprises) will be using IE for years to come!   Cheers, Warren   Edit: typo

            Hi warren.spencer1 thanks for the quick reply.

            Yes, we've done the trivial fix but if the vast majority of the browsers were ignoring it anyway - see browser marketshare - is it worth the effort to push it through...? Maybe just - if only for Edge (even though it's now going to based on Chromium).

            Stephen Montgomery (Inactive) added a comment - Hi warren.spencer1 thanks for the quick reply. Yes, we've done the trivial fix but if the vast majority of the browsers were ignoring it anyway - see browser marketshare - is it worth the effort to push it through...? Maybe just - if only for Edge (even though it's now going to based on Chromium).

            Hello Stephen,

            I can't speak for the rest of the folks here, but my understanding is that the issue is because the cookie is session-based.  Whereas myself (and presumably many of the folks here) would expect that the cookie would survive a browser restart.  In other words after you authenticate I would expect the cookie your browser receives to persist until some predetermined expiry date (possibly the session timeout config setting in crowd?); regardless of how many times the user closes the browser before then.

             

            The fact that some browsers don't clear session cookies is actually a bit of a benefit and may be why more folks aren't affected by this; however on other browsers (notably corporate browsers like IE and Edge) which do clear session cookies when the browser is closed, this causes users to have to log into the services each time they re-open their browser, regardless of whether they checked any remember me checkbox the last time they authenticated.

            Warren Spencer added a comment - Hello Stephen, I can't speak for the rest of the folks here, but my understanding is that the issue is  because the cookie is session-based.  Whereas myself (and presumably many of the folks here) would expect that the cookie would survive a browser restart.  In other words after you authenticate I would expect the cookie your browser receives to persist until some predetermined expiry date (possibly the session timeout config setting in crowd?); regardless of how many times the user closes the browser before then.   The fact that some browsers don't clear session cookies is actually a bit of a benefit and may be why more folks aren't affected by this; however on other browsers (notably corporate browsers like IE and Edge) which do clear session cookies when the browser is closed, this causes users to have to log into the services each time they re-open their browser, regardless of whether they checked any remember me checkbox the last time they authenticated.

            Hi All,

            I'm a Crowd developer tasked with this issue. I attempted to reproduce the behaviour by:

            Next steps:

            • Can impacted watchers monitoring this page tell us what browsers/settings they are seeing this behaviour with?

             

            Stephen Montgomery (Inactive) added a comment - Hi All, I'm a Crowd developer tasked with this issue. I attempted to reproduce the behaviour by: Created Crowd 3.7 AWS instance Created Confluence 6.15 AWS instance Followed https://confluence.atlassian.com/crowd/overview-of-sso-179445277.html + https://confluence.atlassian.com/crowd/integrating-crowd-with-atlassian-confluence-198573.html to configure SSO v1 against the 2 apps. Confirmed that I could log into Confluence using the created Crowd SSO user. Confirmed with FireFox and Chrome that the crowd.token.key had no MaxAge set so cookie is session-based and shouldn't survive a browser restart However with both FireFox and Chrome once restarted, the Confluence session continued on from where it left off ie no expected cookie expiration, no expected logon prompt etc. This unexpected behaviour is to do with modern browser behaviour: https://stackoverflow.com/questions/10617954/chrome-doesnt-delete-session-cookies https://stackoverflow.com/questions/55755511/what-happen-if-cookie-expires-max-age-is-n-a-or-not-set https://bugzilla.mozilla.org/show_bug.cgi?id=345345 On Chrome, switching off "Continue where you left off" and the background sync "Background sync ->Do not allow recently closed sites to finish sending and receiving data" (on Mac) makes no difference - session is still available on restart. However using Incognito mode, I do get the expected Logon screen on every new window restart. On Firefox, switching off "Restore from Session" and disabling "browser.sessionstore.enabled" option from http://wiki.mozilla.org/Session_Restore makes no difference. However like Chrome, using Incognito equivalent ie Private Windows, honours the expected behaviour ie getting a login screen on Private Window shutdown/restart. Probably more to do with cookies being deleted explicitly by FF Private Windows than honouring the expiration. Next steps: Can impacted watchers monitoring this page tell us what browsers/settings they are seeing this behaviour with?  

            l have Crowd Version 3.4.4 and the bug still seems to be there...

            Manse Wolken added a comment - l have Crowd Version 3.4.4 and the bug still seems to be there...

            Can't edit the above comment;  This requires that you edit your SSO cookie from crowd.token_key to crowd_token_key, as nginx can't parse cookies with periods in their name

            Warren Spencer added a comment - Can't edit the above comment;  This requires that you edit your SSO cookie from crowd.token_key to crowd_token_key, as nginx can't parse cookies with periods in their name

            I was able to work around this by using this extraordinarily hacky bit of nginx code

             

            ############
            # SSO Hackiness
            #
            # Because crowd's SSO cookies are session based: https://jira.atlassian.com/browse/CWD-4109
            # We do some serious hacking here to overwrite the cookies so that they expire after a year
            # We can't simply do a map on the response cookie to change its value, because for some reason
            # two cookies are set on login with the same name; the first being empty and the second having
            # the value we are after - nginx when accessing it via $upstream_cookie_... will only return
            $ the first empty one, not the one with a value.  Thus, we do nothing on the initial login
            # and on every request thereafter update the cookie so that it expires in one years time
            ############
            map $upstream_cookie_crowd_token_key $setting_auth_cookie {
                ~*.+ "1";
                default "0";
            }
            map $cookie_crowd_token_key $have_auth_cookie {
                ~*.+ "1";
                default "0";
            }
            map "$have_auth_cookie;$setting_auth_cookie" $auth_name {
                "1;0" "crowd_token_key";
            }
            map $auth_name $auth_value {
                "crowd_token_key" $cookie_crowd_token_key;
            }
            add_header Set-Cookie "$auth_name=$auth_value;Domain=<ENTER DOMAIN HERE>;Path=/;Secure;HttpOnly;Max-Age=31622400" always;
            
            

            Warren Spencer added a comment - I was able to work around this by using this extraordinarily hacky bit of nginx code   ############ # SSO Hackiness # # Because crowd's SSO cookies are session based: https: //jira.atlassian.com/browse/CWD-4109 # We do some serious hacking here to overwrite the cookies so that they expire after a year # We can't simply do a map on the response cookie to change its value, because for some reason # two cookies are set on login with the same name; the first being empty and the second having # the value we are after - nginx when accessing it via $upstream_cookie_... will only return $ the first empty one, not the one with a value. Thus, we do nothing on the initial login # and on every request thereafter update the cookie so that it expires in one years time ############ map $upstream_cookie_crowd_token_key $setting_auth_cookie { ~*.+ "1" ; default "0" ; } map $cookie_crowd_token_key $have_auth_cookie { ~*.+ "1" ; default "0" ; } map "$have_auth_cookie;$setting_auth_cookie" $auth_name { "1;0" "crowd_token_key" ; } map $auth_name $auth_value { "crowd_token_key" $cookie_crowd_token_key; } add_header Set-Cookie "$auth_name=$auth_value;Domain=<ENTER DOMAIN HERE>;Path=/;Secure;HttpOnly;Max-Age=31622400" always;

            is there any way implementing this to my JIRA application without compiling JIRA from scratch? how can I easily build the jar-file from the java-file in my JIRA?

            Robin Lehmann added a comment - is there any way implementing this to my JIRA application without compiling JIRA from scratch? how can I easily build the jar-file from the java-file in my JIRA?

            niv added a comment -

            Hi,

            this is a servlet filter. I just compile it, package it up as a jarfile, drop it into the atlassians' app classpath (app/atlassian-bamboo/WEB-INF/lib/AtlassianSSOCookieFilter.jar, for example), and edit app/atlassian-bamboo/WEB-INF/web.xml so the filter is called (doesn't really matter where in the chain, as long as it sees the cookie):

                <filter>
                  <filter-name>AtlassianSSOCookieFilter</filter-name>
                  <filter-class&gt;AtlassianSSOCookieFilter</filter-class&gt;
                </filter>
                <filter-mapping>
                  <filter-name>AtlassianSSOCookieFilter</filter-name>
                  <url-pattern>/*</url-pattern>
                </filter-mapping>
            

            I'm sure the same can be done with a reverse proxy webserver in front of it - for example, nginx - if one were to hack at it.

            It kind of boggles my mind that no one else has yet to complain about this. Apparently the time where people close tabs or their browser windows is over, so no one notices.

            Cheers
            niv

            niv added a comment - Hi, this is a servlet filter. I just compile it, package it up as a jarfile, drop it into the atlassians' app classpath (app/atlassian-bamboo/WEB-INF/lib/AtlassianSSOCookieFilter.jar, for example), and edit app/atlassian-bamboo/WEB-INF/web.xml so the filter is called (doesn't really matter where in the chain, as long as it sees the cookie): <filter> <filter-name>AtlassianSSOCookieFilter</filter-name> <filter- class& gt;AtlassianSSOCookieFilter</filter- class& gt; </filter> <filter-mapping> <filter-name>AtlassianSSOCookieFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> I'm sure the same can be done with a reverse proxy webserver in front of it - for example, nginx - if one were to hack at it. It kind of boggles my mind that no one else has yet to complain about this. Apparently the time where people close tabs or their browser windows is over, so no one notices. Cheers niv

            Hi ,

            Above suggested class is a new class or are you hooked above code in one of existing class of crowd.

            We are also facing with same issue and planning to follow above suggested solution.

            Regards,
            Ramesh

            Ramesh Udari1 added a comment - Hi , Above suggested class is a new class or are you hooked above code in one of existing class of crowd. We are also facing with same issue and planning to follow above suggested solution. Regards, Ramesh

              Unassigned Unassigned
              prompas Patrice Rompas (Inactive)
              Affected customers:
              27 This affects my team
              Watchers:
              31 Start watching this issue

                Created:
                Updated: