Uploaded image for project: 'atlassian-seraph'
  1. atlassian-seraph
  2. SER-154

request.getRemoteUser() does not return a logged in user

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: High High
    • 2.3.4, 2.4
    • 2.2
    • None
    • true

      This change http://svn.atlassian.com/fisheye/changelog/public?cs=39411 http://svn.atlassian.com/fisheye/cru/CR-517#c3145 has broken confluence's invite plugin.

      The plugin used to rely on the fact that after calling getAuthenticator().login(ServletActionContext.getRequest(), ServletActionContext.getResponse(), username, password, true); the request.getRemoteUser will return the username of logged in user. After we changed the BaseLoginFilter to cache the principle it no longer does that.

      I changed the plugin so it is no longer affected...

          Form Name

            [SER-154] request.getRemoteUser() does not return a logged in user

            bain added a comment -

            You can get at the underlying request using the following code:

                private String getRealRemoteUser(HttpServletRequest request)
                {
                    if (request instanceof HttpServletRequestWrapper)
                    {
                        final ServletRequest unwrap = ((HttpServletRequestWrapper) request).getRequest();
                        if (unwrap instanceof HttpServletRequest)
                        {
                            return ((HttpServletRequest) unwrap).getRemoteUser();
                        }
                    }
                    return request.getRemoteUser();
                }
            

            bain added a comment - You can get at the underlying request using the following code: private String getRealRemoteUser(HttpServletRequest request) { if (request instanceof HttpServletRequestWrapper) { final ServletRequest unwrap = ((HttpServletRequestWrapper) request).getRequest(); if (unwrap instanceof HttpServletRequest) { return ((HttpServletRequest) unwrap).getRemoteUser(); } } return request.getRemoteUser(); }

            Uploaded patch we gave to Confluence customers. See CONF-21201.

            Matthew Erickson added a comment - Uploaded patch we gave to Confluence customers. See CONF-21201 .

            Anatoli added a comment -

            Upped the severity of the issue as it has happened to several customers already.

            Anatoli added a comment - Upped the severity of the issue as it has happened to several customers already.

            bain added a comment - - edited

            SSO generally get exteral website to authenticate the user (e.g. apache to authenticate the user). We can get this user from "HttpServletRequest.getRemoteUser". However, Seraph wraps the HttpServletRequest inside a SecurityHttpRequestWrapper and overwrites the getRemoteUser method to look in the places that Seraph gets the user from (e.g. the session, cookie, basic auth,...). By default, Seraph never calls getRemoteUser to find the user which means SSO wont work. This means that people will be forced to write their own Authenticator. Most of them overwrite the getUserMethod to return the user from the Request:

              public class Example extends DefaultAuthenticator {
            
                public Principal getUser(HttpServletRequest request, HttpServletResponse response) {    
                  return request.getRemoteUser();
                }
             }
            

            In Seraph this used to work in a round about way in 2.1.

            SecurityFilter -> Example.getUser(SecurityHttpRequestWrapper) -> SecurityHttpRequestWrapper.getRemoveUser -> Example.getUser(HttpRequest) -> HttpRequest.getRemoveUser.
            

            Note that Example.getUser is called twice: once with the SecurityHttpRequestWrapper and the next time with the raw HttpRequest. The net result of all these calls is that eventually Example.getUser is given the raw request which allows it to return the user set by the SSO.

            However, since the 2.2 the SecurityHttpRequestWrapper no longer calls back onto Example with the raw request but rather only looks for the user in Seraph cache.

            SecurityFilter -> Example.getUser(SecurityHttpRequestWrapper) -> SecurityHttpRequestWrapper.getRemoveUser -> authenticationContext.getUser()
            

            Unfortunately, this user will never be set because its the SSO that did the authentication and not Seraph. The means that the Example.getUser(SecurityHttpRequestWrapper) will always return null.

            bain added a comment - - edited SSO generally get exteral website to authenticate the user (e.g. apache to authenticate the user). We can get this user from "HttpServletRequest.getRemoteUser". However, Seraph wraps the HttpServletRequest inside a SecurityHttpRequestWrapper and overwrites the getRemoteUser method to look in the places that Seraph gets the user from (e.g. the session, cookie, basic auth,...). By default, Seraph never calls getRemoteUser to find the user which means SSO wont work. This means that people will be forced to write their own Authenticator . Most of them overwrite the getUserMethod to return the user from the Request : public class Example extends DefaultAuthenticator { public Principal getUser(HttpServletRequest request, HttpServletResponse response) { return request.getRemoteUser(); } } In Seraph this used to work in a round about way in 2.1. SecurityFilter -> Example.getUser(SecurityHttpRequestWrapper) -> SecurityHttpRequestWrapper.getRemoveUser -> Example.getUser(HttpRequest) -> HttpRequest.getRemoveUser. Note that Example.getUser is called twice: once with the SecurityHttpRequestWrapper and the next time with the raw HttpRequest. The net result of all these calls is that eventually Example.getUser is given the raw request which allows it to return the user set by the SSO. However, since the 2.2 the SecurityHttpRequestWrapper no longer calls back onto Example with the raw request but rather only looks for the user in Seraph cache. SecurityFilter -> Example.getUser(SecurityHttpRequestWrapper) -> SecurityHttpRequestWrapper.getRemoveUser -> authenticationContext.getUser() Unfortunately, this user will never be set because its the SSO that did the authentication and not Seraph. The means that the Example.getUser(SecurityHttpRequestWrapper) will always return null.

            Matthew Erickson added a comment - - edited

            This is also a problem for customers who have custom authenticators in Confluence if they rely on request.getRemoteUser() to return the logged in user, for example if the user has alrerdy been logged in using SSO.

            Matthew Erickson added a comment - - edited This is also a problem for customers who have custom authenticators in Confluence if they rely on request.getRemoteUser() to return the logged in user, for example if the user has alrerdy been logged in using SSO.

              merickson Matthew Erickson
              akazatchkov Anatoli
              Affected customers:
              2 This affects my team
              Watchers:
              4 Start watching this issue

                Created:
                Updated:
                Resolved:
                14 years, 29 weeks, 2 days ago