Uploaded image for project: 'RH-SSO'
  1. RH-SSO
  2. RHSSO-2149

RH SSO exception due to requirement of client_id" presence within Request Object

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Critical Critical
    • None
    • None
    • Protocol - OIDC, Server
    • None
    • False
    • None
    • False

      Environment Details
      ===================

      RH-SSO version: 7.6.0

      Issue Description:
      ===================

      A thirdparty OIDC client registered in RH SSO is using the authorisation code grant flow.
      The authorization request is build by this OIDC client and the "request_uri" request parameter is provided.

      When RH SSO tries to handle the JWE Encrypted Request Object obtained through the "request_uri" request parameter, we can see that RH SSO verifies that the "client_id" claim is present within the decrypted request object and is the same as the "client_id" provided request parameter. Request Object provided by a thirdparty OIDC Client doesn't contain this claim as this is not a mandatory claim in the OIDC specifications.

      The OIDC specification states that for the request to be a valid OAuth 2.0 Authorization Request, " values for the response_type and client_id parameters MUST be included using the OAuth 2.0 request syntax, since they are REQUIRED by OAuth 2.0. The values for these parameters MUST match those in the Request Object, if present." 
      [OIDC Specification](https://openid.net/specs/openid-connect-core-1_0.html#RequestUriParameter)

      The "response_type" and "client_id" request parameters are indeed provided by this thirdparty OIDC client but are not present in the Request Object because these values are optional within it. So the validation against the "client_id" should be done only if the claim is provided in the Request Object only... and then the presence of this claim shouldn't be mandatory as today within RH SSO

       

      Auth Request Endpoint
      https://www.partenaire.com/authorize?response_type=code &redirect_uri=https%3A%2F%2Frqt-acs1-3dsecure.cm-cic.com%2Fpartenaire%2Ffr%2Fopenid_callback.cgi &request_uri=https%3A%2F%2Frqt-acs1-3dsecure.cmcic.com%2Fpartenaire%2Ffr%2Ftransaction_information.cgi%3Ftransaction_id%3Dy97RbL9zsc3Je4f4eTB416LI WC69lesK &scope=openid%2Bservices%3AACS_CONFIRM &client_id=i7PFPs86dEu6U78Qkt95VgR6s2Xai1uQ &state=NB320zirl1Es9VOXk6UVn9UVds8i830w &nonce=Wocxp6m0PbP17OGHidq054ZN33oB09zH

      Decrypted Request Object

      {  "merchantName": "MarchandTest",  "merchantUrl": "www.marchand.com",  "amount": 4587,  "exponent": 2,  "currency": "978",  "transactionDate": "2020-11-13 16:42:50",  "panMasked": "466258xxxxxx0259",  "contratNumber": "03515361313",  "customerReference": "622424124100281880403" }

       

      Action Taken:
      =============

      server.log
      =========

      2022-08-09 09:18:05,998 TRACE [org.keycloak.models.jpa.JpaRealmProvider] (default task-1) getClientByClientId(3ds@0000cc02, ywlyWMIjEGEvlxfHW0k6kb4YYpHh39mf)
          org.jboss.logmanager.ExtLogRecord.formatRecord(ExtLogRecord.java:505)
      ...
      2022-08-09 09:18:06,001 TRACE [org.keycloak.models.jpa.JpaRealmProvider] (default task-1) getClientById(3ds@0000cc02, 9a7c0641-38d1-4042-a5fc-875afc145893)
          org.jboss.logmanager.ExtLogRecord.formatRecord(ExtLogRecord.java:505)
      ...
      2022-08-09 09:18:12,222 WARN  [org.keycloak.services] (default task-1) KC-SERVICES0097: Invalid request: java.lang.RuntimeException: Request object must be set with the client_id
          at org.keycloak.protocol.oidc.endpoints.request.AuthzEndpointRequestObjectParser.<init>(AuthzEndpointRequestObjectParser.java:55)
          at org.keycloak.protocol.oidc.endpoints.request.AuthorizationEndpointRequestParserProcessor.parseRequest(AuthorizationEndpointRequestParserProcessor.java:96)
          at org.keycloak.protocol.oidc.endpoints.AuthorizationEndpoint.process(AuthorizationEndpoint.java:132)
          at org.keycloak.protocol.oidc.endpoints.AuthorizationEndpoint.buildGet(AuthorizationEndpoint.java:112)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.lang.reflect.Method.invoke(Method.java:498)
      ...
      2022-08-09 09:18:12,310 TRACE [org.keycloak.events] (default task-1) type=LOGIN_ERROR, realmId=3ds, clientId=ywlyWMIjEGEvlxfHW0k6kb4YYpHh39mf, userId=null, ipAddress=127.0.0.1, error=invalid_request, requestUri=http://localhost:8080/auth/realms/3ds/protocol/openid-connect/auth?response_type=code&redirect_uri=https%3A%2F%2Frqt-acs2-3dsecure.cm-cic.com%2Fmartinmaurel%2Ffr%2Fopenid_callback.cgi&scope=openid%2Bservice%3AACS_CONFIRM&request_uri=https%3A%2F%2Frqt-acs2-3dsecure.cm-cic.com%2Fmartinmaurel%2Ffr%2Ftransaction_information.cgi%3Ftransaction_id%3D82022088-cd68-44b1-a87f-b56c0c4522dc&client_id=ywlyWMIjEGEvlxfHW0k6kb4YYpHh39mf&state=NB320zirl1Es9VOXk6UVngUVds8i830w&nonce=Wocxp6m05bP17OGHidq054ZN33oB09zH, stackTrace=
          org.keycloak.events.log.JBossLoggingEventListenerProvider.logEvent(JBossLoggingEventListenerProvider.java:114)

       

      Notes:
      =====

      The change should be done in the following class
      https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/protocol/oidc/endpoints/request/AuthzEndpointRequestObjectParser.java

      In particular...

               if (clientId == null)

      {             throw new RuntimeException("Request object must be set with the client_id");         }

              if (!client.getClientId().equals(clientId.asText()))

      {             throw new RuntimeException("The client_id in the request object is not the same as the authorizing client");         }

      should be changed into  

              if (clientId != null && !client.getClientId().equals(clientId.asText())) {             throw new RuntimeException("The client_id in the request object is not the same as the authorizing client");         }

       

      Workaround
      ===========
      Updated source file of AuthzEndpointRequestObjectParser
      Updated source file of AuthzEndpointRequestParser

      https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/protocol/oidc/endpoints/request/AuthzEndpointRequestParser.java

      https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/protocol/oidc/endpoints/request/AuthzEndpointRequestObjectParser.java

      Queries:
      =========
      1) Is the "client_id" claim mandatory in the object request (current RH SSO mode) ?

      2) Is the overriding of each authorization endpoint request attribute, with the one available from the one in the object request even if it is null, correct (current RH SSO mode) ?

      3) Regarding the RFC9101 ("The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR)"), the "client_id" claim seems indeed mandatory.
      However, it doesn't seem correct to override the authorization endpoint request attributes with null values if not present in the request object.

              Unassigned Unassigned
              rhn-support-oidehen Osarobo Idehen
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Created:
                Updated: