Uploaded image for project: 'XNAT'
  1. XNAT
  2. XNAT-5954

Authenticating with alias tokens and basic auth creates a new session on each request

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 1.7.5
    • Fix Version/s: 1.7.5.3
    • Component/s: Security
    • Labels:
    • Rank:
      0|0hzz0v:r

      Description

      When using basic authentication with the user's name and password, XNAT checks whether the current session is already authenticated with the same user object by checking the username passed on the Authorization header against the security principal in the HTTP session. If the usernames match, it doesn't authenticate, but just uses the existing session. In practice, this looks like this:

      $ http --auth admin:admin --session=admin http://xnat-dev05.nrg.mir/xapi/siteConfig/buildInfo
      HTTP/1.1 200 OK
      Set-Cookie: JSESSIONID=83F4414ADFA31E8087720B64BDF61680; Path=/; HttpOnly
       
      $ http --auth admin:admin --session=admin --verbose http://xnat-dev05.nrg.mir/xapi/siteConfig/buildInfo
      Cookie: JSESSIONID=83F4414ADFA31E8087720B64BDF61680; SESSION_EXPIRATION_TIME="1549909058414,900000"
       
      HTTP/1.1 200 OK
      Set-Cookie: SESSION_EXPIRATION_TIME="1549909074905,900000"; Version=1; Path=/
       
      $ http --auth admin:admin --session=admin --verbose http://xnat-dev05.nrg.mir/xapi/siteConfig/buildInfo
      Cookie: JSESSIONID=83F4414ADFA31E8087720B64BDF61680; SESSION_EXPIRATION_TIME="1549909074905,900000"
       
      HTTP/1.1 200 OK
      Set-Cookie: SESSION_EXPIRATION_TIME="1549909084503,900000"; Version=1; Path=/
       
      $ http --auth admin:admin --session=admin --verbose http://xnat-dev05.nrg.mir/data/services/tokens/issue
      Cookie: JSESSIONID=83F4414ADFA31E8087720B64BDF61680; SESSION_EXPIRATION_TIME="1549909084503,900000"
       
      HTTP/1.1 200 OK
      Set-Cookie: SESSION_EXPIRATION_TIME="1549909095434,900000"; Version=1; Path=/
      

      Note that the only cookie that gets set on each request is SESSION_EXPIRATION_TIME and the value passed for JSESSIONID stays the same across the requests. Now compare this to using an alias token:

      $ http --auth <alias>:<secret> --session=admin-token --verbose http://xnat-dev05.nrg.mir/xapi/siteConfig/buildInfo
      Cookie: JSESSIONID=4FDD15DAE76B63A641995988BBF80552; SESSION_EXPIRATION_TIME="1530283482084,900000"
       
      HTTP/1.1 200 OK
      Set-Cookie: JSESSIONID=C2FE5BA34DD37C32D3D3DCE4B8354DDE; Path=/; HttpOnly
      Set-Cookie: SESSION_EXPIRATION_TIME="1549909130428,900000"; Version=1; Path=/
       
      $ http --auth <alias>:<secret> --session=admin-token --verbose http://xnat-dev05.nrg.mir/xapi/siteConfig/buildInfo
      Cookie: JSESSIONID=C2FE5BA34DD37C32D3D3DCE4B8354DDE; SESSION_EXPIRATION_TIME="1549909130428,900000"
       
      HTTP/1.1 200 OK
      Set-Cookie: JSESSIONID=58EA96CB35A73878ADC4510CF8A4669C; Path=/; HttpOnly
      Set-Cookie: SESSION_EXPIRATION_TIME="1549909134703,900000"; Version=1; Path=/
       
      $ http --auth <alias>:<secret> --session=admin-token --verbose http://xnat-dev05.nrg.mir/xapi/siteConfig/buildInfo
      Cookie: JSESSIONID=58EA96CB35A73878ADC4510CF8A4669C; SESSION_EXPIRATION_TIME="1549909134703,900000"
       
      HTTP/1.1 200 OK
      Set-Cookie: JSESSIONID=E97332B9BAC4B8523C3AAEF3C413EA0C; Path=/; HttpOnly
      Set-Cookie: SESSION_EXPIRATION_TIME="1549909136135,900000"; Version=1; Path=/
       
      $ http --auth <alias>:<secret> --session=admin-token --verbose http://xnat-dev05.nrg.mir/xapi/siteConfig/buildInfo
      Cookie: JSESSIONID=E97332B9BAC4B8523C3AAEF3C413EA0C; SESSION_EXPIRATION_TIME="1549909136135,900000"
       
      HTTP/1.1 200 OK
      Set-Cookie: JSESSIONID=2612A36F31905F2C22D7422921D30CE8; Path=/; HttpOnly
      Set-Cookie: SESSION_EXPIRATION_TIME="1549909144848,900000"; Version=1; Path=/
      

      Note that a new value is returned for JSESSIONID on each request and that JSESSIONID is passed back to the server on the subsequent request.

      The root problem is that XNAT and Spring Security check the authentication header's username against the cached security principal, but the alias token of course doesn't match the username.

        Activity

        Hide
        jrherrick@wustl.edu Rick Herrick added a comment -

        There was a fair amount of refactoring I did to streamline a couple of operations, most notably recording user logins (moved to Users.recordUserLogin()), but the core change to address this particular issue is in the method XnatBasicAuthenticationFilter.authenticationIsRequired(). This checks the cached principal name against the username extracted from the header and the username from the row in the alias token service where the alias matches the extracted "username".

        Performing the same operations as described in the main issue gives the following results (this only shows the alias token results and not the username/password results, since those show the expected behavior above):

        $ http --auth <alias>:<secret> --session=admin --verbose --verify=no https://xnatdev.xnat.org/xapi/siteConfig/buildInfo
        Cookie: JSESSIONID=BEA6CA5C67C3F8AA1CB57E80BB5BD3AE; SESSION_EXPIRATION_TIME="1549910576860,900000"
         
        HTTP/1.1 200 OK
        Set-Cookie: SESSION_EXPIRATION_TIME="1549910602191,900000"; Version=1; Path=/
         
        $ http --auth <alias>:<secret> --session=admin --verbose --verify=no https://xnatdev.xnat.org/xapi/siteConfig/buildInfo
        Cookie: JSESSIONID=BEA6CA5C67C3F8AA1CB57E80BB5BD3AE; SESSION_EXPIRATION_TIME="1549910602191,900000"
         
        HTTP/1.1 200 OK
        Set-Cookie: SESSION_EXPIRATION_TIME="1549910605705,900000"; Version=1; Path=/
         
        $ http --auth <alias>:<secret> --session=admin --verbose --verify=no https://xnatdev.xnat.org/xapi/siteConfig/buildInfo
        Cookie: JSESSIONID=BEA6CA5C67C3F8AA1CB57E80BB5BD3AE; SESSION_EXPIRATION_TIME="1549910605705,900000"
         
        HTTP/1.1 200 OK
        Set-Cookie: SESSION_EXPIRATION_TIME="1549910606558,900000"; Version=1; Path=/
         
        $ http --auth <alias>:<secret> --session=admin --verbose --verify=no https://xnatdev.xnat.org/xapi/siteConfig/buildInfo
        Cookie: JSESSIONID=BEA6CA5C67C3F8AA1CB57E80BB5BD3AE; SESSION_EXPIRATION_TIME="1549910606558,900000"
         
        HTTP/1.1 200 OK
        Set-Cookie: SESSION_EXPIRATION_TIME="1549910607414,900000"; Version=1; Path=/
         
        $ http --auth <alias>:<secret> --session=admin --verbose --verify=no https://xnatdev.xnat.org/xapi/siteConfig/buildInfo
        Cookie: JSESSIONID=BEA6CA5C67C3F8AA1CB57E80BB5BD3AE; SESSION_EXPIRATION_TIME="1549910607414,900000"
         
        HTTP/1.1 200 OK
        Set-Cookie: SESSION_EXPIRATION_TIME="1549910608733,900000"; Version=1; Path=/
        

        Notice that Set-Cookie is only passed back for SESSION_EXPIRATION_TIME as expected and the same value for JSESSIONID is used for each call.

        Show
        jrherrick@wustl.edu Rick Herrick added a comment - There was a fair amount of refactoring I did to streamline a couple of operations, most notably recording user logins (moved to Users.recordUserLogin() ), but the core change to address this particular issue is in the method XnatBasicAuthenticationFilter.authenticationIsRequired() . This checks the cached principal name against the username extracted from the header and the username from the row in the alias token service where the alias matches the extracted "username". Performing the same operations as described in the main issue gives the following results (this only shows the alias token results and not the username/password results, since those show the expected behavior above): $ http --auth <alias>:<secret> --session=admin --verbose --verify=no https://xnatdev.xnat.org/xapi/siteConfig/buildInfo Cookie: JSESSIONID=BEA6CA5C67C3F8AA1CB57E80BB5BD3AE; SESSION_EXPIRATION_TIME="1549910576860,900000"   HTTP/1.1 200 OK Set-Cookie: SESSION_EXPIRATION_TIME="1549910602191,900000"; Version=1; Path=/   $ http --auth <alias>:<secret> --session=admin --verbose --verify=no https://xnatdev.xnat.org/xapi/siteConfig/buildInfo Cookie: JSESSIONID=BEA6CA5C67C3F8AA1CB57E80BB5BD3AE; SESSION_EXPIRATION_TIME="1549910602191,900000"   HTTP/1.1 200 OK Set-Cookie: SESSION_EXPIRATION_TIME="1549910605705,900000"; Version=1; Path=/   $ http --auth <alias>:<secret> --session=admin --verbose --verify=no https://xnatdev.xnat.org/xapi/siteConfig/buildInfo Cookie: JSESSIONID=BEA6CA5C67C3F8AA1CB57E80BB5BD3AE; SESSION_EXPIRATION_TIME="1549910605705,900000"   HTTP/1.1 200 OK Set-Cookie: SESSION_EXPIRATION_TIME="1549910606558,900000"; Version=1; Path=/   $ http --auth <alias>:<secret> --session=admin --verbose --verify=no https://xnatdev.xnat.org/xapi/siteConfig/buildInfo Cookie: JSESSIONID=BEA6CA5C67C3F8AA1CB57E80BB5BD3AE; SESSION_EXPIRATION_TIME="1549910606558,900000"   HTTP/1.1 200 OK Set-Cookie: SESSION_EXPIRATION_TIME="1549910607414,900000"; Version=1; Path=/   $ http --auth <alias>:<secret> --session=admin --verbose --verify=no https://xnatdev.xnat.org/xapi/siteConfig/buildInfo Cookie: JSESSIONID=BEA6CA5C67C3F8AA1CB57E80BB5BD3AE; SESSION_EXPIRATION_TIME="1549910607414,900000"   HTTP/1.1 200 OK Set-Cookie: SESSION_EXPIRATION_TIME="1549910608733,900000"; Version=1; Path=/ Notice that Set-Cookie is only passed back for SESSION_EXPIRATION_TIME as expected and the same value for JSESSIONID is used for each call.

          People

          • Assignee:
            moore.c@wustl.edu Charlie Moore
            Reporter:
            jrherrick@wustl.edu Rick Herrick
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Time Tracking

              Estimated:
              Original Estimate - 0 minutes
              0m
              Remaining:
              Remaining Estimate - 0 minutes
              0m
              Logged:
              Time Spent - 4 hours
              4h