Uploaded image for project: 'Red Hat build of Keycloak'
  1. Red Hat build of Keycloak
  2. RHBK-3715

Incorrect scheme in the WWW-Authenticate when Authorization: DPoP used [GHI#42706]

XMLWordPrintable

    • False
    • Hide

      None

      Show
      None
    • False

      Before reporting an issue

      [x] I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.

      Area

      oidc

      Describe the bug

      I've sent an UserInfo request with invalid DPoP proof with headers like:

      {
        "endpoint" : "https://as.keycloak-fapi.org:8443/realms/test/protocol/openid-connect/userinfo",
        "Headers" : {
      

      "Authorization" : "DPoP eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJYUHlTRV9fQk9lY2pxTVA2V0FIemk5SEFQMFgyaWxpVDRfamVmV0paVGlzIn0.eyJleHAiOjE3NTgxMTU2MzIsImlhdCI6MTc1ODExNTMzMiwiYXV0aF90aW1lIjoxNzU4MTEyOTM1LCJqdGkiOiJvbnJ0cnQ6ZWM2N2E3NWEtMTBhNy0zOTBhLTQwZjYtYmQ4NTFjNjQwNmUyIiwiaXNzIjoiaHR0cHM6Ly9hcy5rZXljbG9hay1mYXBpLm9yZzo4NDQzL3JlYWxtcy90ZXN0IiwiYXVkIjoiYWNjb3VudCIsInN1YiI6ImVkYTk2ODNjLTljMWMtNGUzOS1hOTUyLTgwNGU2M2JjZWY5ZCIsInR5cCI6IkRQb1AiLCJhenAiOiI5OTAxYzZhYy00Yjc3LTRhZDYtODcyMS0wNTc5NmRjZTc2ZjkiLCJzaWQiOiI0Y2M1Njg3ZS1kMzU2LWNjZmYtYzk4MS04NWJhM2Q2MTBkODYiLCJhY3IiOiIwIiwiYWxsb3dlZC1vcmlnaW5zIjpbImh0dHBzOi8vYXBwLmtleWNsb2FrLWZhcGkub3JnOjg1NDMiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImRlZmF1bHQtcm9sZXMtdGVzdCIsIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJjbmYiOnsiamt0IjoiMXlOVnNMWS1oM0JSRFNHNVFsTDRFaFlFLTYyT0xONENWdFJUVWtkdHdzUSJ9LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiSm9obiBCYXIiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJqb2huIiwiZ2l2ZW5fbmFtZSI6IkpvaG4iLCJmYW1pbHlfbmFtZSI6IkJhciIsImVtYWlsIjoiam9obkBlbWFpbC5jeiJ9.R15ATuW3mCvRgk-4869m28vyc0jExqyxDr5ywMIfDxvZhfaQJsdkQ-dJPDSPVOW1JoIXtNTP_UqIQhz6C72FaestBSad3wdXowS6HcJyjvXNcLQWzZeyyB7hSRQOK8bC0FEhLRgK9bOe0BnzD09OPNXSAwh4oLmpjxLtuuHjhRUKJojlGBzwkSOmuH6JU1Kse2xACPszJtW1IMwv2knJnEitJUHvLBC0bqNMvIA7FApwy0BrR52OnjCSsaSyFqNhZDckDTgdV9iUDhcHlsiJVsLe5lY__it1yEJeHrRoY84oikZ0cuDYg7L-LkNl9ra-yW2Y9sF_By_w8dy69LVThA",
      "Accept" : "application/json",
      "DPoP" : "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiZHBvcCtqd3QiLCJraWQiIDogInFQcGFBQjllU0pXelc1czVYMmFFdkdTNlVlejhSNUw4N2hVVElORHBoa1UiLCJqd2siIDogeyJraWQiOiJxUHBhQUI5ZVNKV3pXNXM1WDJhRXZHUzZVZXo4UjVMODdoVVRJTkRwaGtVIiwia3R5IjoiUlNBIiwidXNlIjoic2lnIiwibiI6InFzMEFDNEljd1BzV3JFV1BxdEZiVXV1WTkxU2QwaDhBUXRWMEtrdzcxYkYxZW9NT3pVbWdQNkViaFFDdWxrbGFDejljd0ZudDdZbUFfQ0R3ZTRkWlRwQUVaNnNmMjgtSXVGX2tfZDFiangyM1ZNTDlndm80akViWUw0ay1lQzVnMTZuNklqTkZJbzZuZzh3cnBKR25YSTVoZ2t5Y2ZmY0NZMktHZG1wZFJYcDdQVHNGaWZBZEtLcGp6TUczR3R2cjVHLTNTa2RXUFRWU3JydW5mNFVBVGgyckcyZ0RvRUhKMGhoVXdDaUg0OUo3ckc5Q0FvMmZmZ3pkUkJuQnlRVzFVMWk3U2JYdGRtTjN4azNiZ1pYQ1NnOEhMN3E5UWVpVW00VmE2QTBpaWJ1ZnJwVF9uZ0twTE84WUg1NkZNMncxeVVuQUpxSk9mNnVMOVZKWUhMTHhDdyIsImUiOiJBUUFCIn19.eyJpYXQiOjE3NTgxMTUzODUsImp0aSI6IjRiNGIzMWI4LWM3ZTEtYjNiZi0xNjZjLWRlYmVmZWJmNDY3MCIsImF0aCI6IjNFOGF6cU9zblNGRzN5eV85bmplMWlCR3dIZTZUQ3J5dTZCajlBQ0pPTlEiLCJodG0iOiJHRVQiLCJodHUiOiJodHRwczovL2FzLmtleWNsb2FrLWZhcGkub3JnOjg0NDMvcmVhbG1zL3Rlc3QvcHJvdG9jb2wvb3BlbmlkLWNvbm5lY3QvdXNlcmluZm8ifQ.lntPWrJe6JC_obNKB5c0lXbu8I87_U78WZ-8f_l_BmE66XsGdLh4FVHJek-kqbRurEyfe3RI-MqoNtja3_D08UoNoZbnsAcL4liszE2zxlDbFD4i1ZDtrNyHLS-UNpaj1KcmB9y3zgGgIR9I6FsONIFn3iKt8A0ryJTUocoew_2bhej5tEmhMQVqW6Pc676OaIYVtIiqOpMdlfyhOQ08QsH1CmjkcfdqQd2D-GeP9mMzVrOZjvos2FRwczycahDSOPLLJQVBZkBWYyF0CwJegObN7RboH02fEjz4qZzWjlAEwj0db7YEu1VA4yrB4-Foy9aLryZpHIyJr6fHABo7iQ"

        }
      }
      

      The response looks like this:

      {
        "statusCode" : 401,
        "headers" : {
      

      "Referrer-Policy" : "no-referrer",
      "content-length" : "0",
      "Strict-Transport-Security" : "max-age=31536000; includeSubDomains",
      "X-Content-Type-Options" : "nosniff",
      "WWW-Authenticate" : "Bearer realm=\"test\", error=\"invalid_token\", error_description=\"Token verification failed\"",
      "Content-Type" : "text/plain;charset=utf-8"

        },
        "success" : false
      }
      

      The response did contains WWW-Authenticate header with the scheme Bearer, which is a bit strange as I've used Authorization: DPoP and hence I would expect WWW-Authenticate: DPoP ... response header instead.

      The user-info endpoint is supposed to support rfc6750 according to the OIDC Core specification and the DPoP specification specifies that WWW-Authenticate: DPoP ... might be used in such cases. Especially in this section https://datatracker.ietf.org/doc/html/rfc9449#section-7.2 , it mentions that:

      If the mechanism used to attempt authentication could be established unambiguously, then the corresponding challenge SHOULD be used to deliver error information (Figure 18).
      

      Based on that, my understanding is, that it would be better to use WWW-Authenticate: DPoP ... in this challenge.

      Per my understanding, I can imagine this behaviour:

      • If user-info request was sent with Authorization: Bearer incorrect-access-token, I expect that WWW-Authenticate header will contain Bearer scheme as it is now.
      • If user-info request was sent with Authorization: DPoP incorrect-access-token, I expect that WWW-Authenticate header will contain DPoP challenge instead of Bearer.
      • If user-info request was sent without Authorization header (or with incorrect scheme), we might use WWW-Authenticate with both Bearer and DPoP . However for the backwards compatibility, it may be better to stick just with Bearer as it is possible that some clients might see compatibility issues if we start to include DPoP header automatically. Per my understanding, we are not required to include DPoP in such a case. So my vote is to still only use Bearer as we are doing today.

      Version

      nightly (from 2025-09-17)

      Regression

      [ ] The issue is a regression

      Expected behavior

      The WWW-Authenticate: DPoP header will be used in the case when 401 is returned from the userInfo request

      Actual behavior

      The WWW-Authenticate: Bearer header is used in the case when 401 is returned from the userInfo request

      How to Reproduce?

      See the details

      Anything else?

      This is specific to the user-info endpoint. The other Keycloak endpoints accepting Authorization: DPoP header (EG. admin REST API or account REST API) currently does not return WWW-Authenticate header at all and is not strictly treated as rfc6750 aware response.

              Unassigned Unassigned
              pvlha Pavel Vlha
              Keycloak Core Clients
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated:
                Resolved: