Request Object Support for WSO2 Identity Server

Purpose of Request Object in OIDC

Usually in OIDC the returning claims will be filtered from the requested scopes that is passed to the server as an query param with the authorization request. When it comes to wso2 IS server, it filters the requested claims both from the requested scopes defined with the authorization request and the requested claims that can be configured in service provider configurations. But if Request Object is associated with the authorization request, then the server will return the essential request object claims if those claims are requested from the scope.

This request object can be either
1.  request parameter (Passed by value)
2.  request_uri parameter (Passed by reference)

'request' parameter

As we previously discussed the main purpose of this parameter is for supporting to request some claims other than the default Userinfo and IdToken claim set which is associated with the requested scope. This parameter value can be a pure json object or an encoded json object. 

Lets consider following sample request which contains pure json as the request parameter value.
https://localhost:9443/oauth2/authorize?
    response_type=code%20id_token
    &client_id=XXXXX
    &redirect_uri=http://localhost:8080/playground
    &scope=openid address
    &state=af0ifjsldkj
    &nonce=n-0S6_WzA2Mj
    &request={
  "iss": "s6BhdRkqt3",
  "aud": "https://server.example.com",
  "response_type": "code id_token",
  "client_id": "s6BhdRkqt3",
  "redirect_uri": "https://client.example.org/cb",
  "scope": "openid",
  "state": "af0ifjsldkj",
  "nonce": "n-0S6_WzA2Mj",
  "max_age": 86400,
  "claims": {
  "userinfo": {
  "given_name": {
  "essential": true
  },
 "nickname": null,
 "email": {
 "essential": true
  },
 "email_verified": {
 "essential": true
  },
  "picture": null
  },
 "id_token": {
  "gender": null,
  "email": {
  "essential": true
  },
  }
}
}

If we process the above request it requests some claims from both the members user info endpoint and id token. 'given_name' and 'email' are marked as essential claims from user info endpoint and email is requested as an essentila claim from id token. 

From the server side following validations will be done.
1. The client_id and response_type of the request object (if present) should be equal to the client_id and the response_type of the authorization request.
2. The authorization request query params will be overridden from the  request/request_uri parameter values if they are present in the request/request_uri parameter
3. Both the request and request_uri parameters can not be associated with the same authorization request.

IS server will respond as follows for the above sample request.
1. Here the requested scope is considered as 'openid email' as the scope value of the request object is declared. So the server will ignore the scope value which is associated with the authorization request and consider the requested scope as 'openid email'
2.Consider the claims "given_name" and "email" which are marked as 'essential:true' for 'userinfo' member. Even if they are not mapped with the openid or address scope in the registry,  if these claims are requested claims, then 'given_name' and 'email' will be returned from the Userinfo endpoint. So as a summary the claims which have marked as 'essential : true' only get controlled by the requested claims and ignore the requested scopes. If the server can not provide those essential claims there wont be any failure or error message returning from the server.

2. The claims like "nickname" it will act as a default claim and will control by both requested scopes and the requested claims.

3. If the server can not provide the requested essential claims the server will return null for the specific claim and the flow will not break.

4. This behavior is common to the id token as well.


Signature Validation

The request parameter value can be even a JWS or a JWE. If it is a JWS it will consist of three parts which is separated from 2 '.' characters those are JOSE header, JWS payload and JWS signature. So from the JOSE header the server will extract one of the following values to calculate the certificate thumbprint.
 jku,jwk,kid,x5u,x5c,x5t and x5t#s256
If the header does not contain one of the above values we simply reject do the signature validation. Based on the certificate value it will generate the public key and using the nimbus library it will validate the signature.

Decryption

The request parameter value can be a even a JWE. If it is a JWE it will consist of five parts which is separated from 4 '.'  characters those are JOSE header, JWE encrypted key , Initialization vector, Cipher text and Authentication tag. After doing a base64 encoding the values of those five sections can be seen. JOSE header is consists of 'alg' and 'enc' values. Algorithm defined in 'enc' is used to do the content encryption while the algorithm defined in the 'alg' is used to do the key wrapping. Here we have used nimbus library for the decryption by providing the IS private key.

If the jwt is a nested one then the payload (Cipher Text) of the jwt is a signed one. So the server will decrypt the string first and then check the payload for signature validation.

All the validations and the request object builder are extensible so a third party user can build the request object and do any validations in their own way. At the moment IS server does not have a default implementation for request_uri parameter and instead we do extract the request_uri parameter from the request object and pass it. So externally a user can write a builder to build the request_uri parameter and do their customizations.

Following configuration changes should be done in identity.xml when writing extension points for this feature.

  <OpenIDConnect>
  <RequestObjectBuilder>
  <BuilderName>request_param_value_builder</BuilderName>
  <RequestObjectBuilderImplClass>org.wso2.carbon.identity.openidconnect.RequestParamRequestObjectBuilder</RequestObjectBuilderImplClass>
  </RequestObjectBuilder>
  <RequestObjectValidator>org.wso2.carbon.identity.openidconnect.RequestObjectValidatorImpl</RequestObjectValidator>
  </OpenIDConnect>

 If the configuration is not present the default classes will be executed.

Comments

Popular posts from this blog

Applying CORS Filter to wso2 Identity Server

JWKS endpoint of wso2 IS

DCR VS DCRM with WSO2 Identity server