Skip to content

Commit

Permalink
[WFLY-17143] Add the ability to specify that the OIDC Authentication …
Browse files Browse the repository at this point in the history
…Request should include request and request_uri parameters
  • Loading branch information
Prarthona Paul committed Aug 29, 2023
1 parent 0b96497 commit 9491f5b
Showing 1 changed file with 177 additions and 0 deletions.
177 changes: 177 additions & 0 deletions elytron/WFLY-17143-request-uri-parameters.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
= Add the ability to specify that the OIDC Authentication Request should include request and request_uri parameters
:author: Prarthona Paul
:email: [email protected]
:toc: left
:icons: font
:idprefix:
:idseparator: -

== Overview

OpenID Connect is an authentication mechanism that builds on OAuth 2.0 and allows a user to login to a web application using credentials established by an OpenID provider. Authentication requests sent using OpenID Connect can be signed and optionally encrypted by encoding query parameters in a JWT. This can be achieved using one of two auth request parameters: `request` and `request_uri`, which are both optional. The current version of `elytron-oidc-client` does not allow the user to specify `request` or `request_uri`. Instead, all requests are sent in using the OAuth 2.0 request syntax. This RFE will add an attribute to the `elytron-oidc-client` subsystem called `authentication-request-format`, which can allow the user to specify if they will use either of the request parameters. We will also add 3 additional attributes called `request-object-signing-algorithm`, `request-object-encryption-algorithm` and `request-object-content-encryption-algorithm`, which will be used to specify if and how the request parameters will be signed and/or encrypted.

According to the https://openid.net/specs/openid-connect-core-1_0.html#JWTRequests[OpenID docs], requests using these parameters are represented as JWTs, which are respectively passed by value or by reference. Depending on the OpenID Provider, support for `request` may or may not be available.

== Issue Metadata

=== Issue

* https://issues.redhat.com/browse/WFLY-17143[WFLY-17143]

=== Related Issues

* https://issues.redhat.com/browse/EAP7-1974[EAP7-1974]
* https://issues.redhat.com/browse/ELY-2584[ELY-2584]

=== Dev Contacts

* mailto:{email}[{author}]

=== QE Contacts

=== Testing By
* [x] Engineering

* [ ] QE

=== Affected Projects or Components

* WildFly
* WildFly Elytron

=== Other Interested Projects

N/A

=== Relevant Installation Types
* [x] Traditional standalone server (unzipped or provisioned by Galleon)

* [x] Managed domain

* [x] OpenShift s2i

* [x] Bootable jar

== Requirements

=== Hard Requirements

* A new attributes named `authentication-request-format`, `request-object-signing-algorithm`, `request-object-encryption-algorithm` and `request-object-content-encryption-algorithm` will be added to the `secure-deployment`, `secure-server`, `realm` and `provider` resources under the `elytron-oidc-client` subsystem. The value for the `authentication-request-format` attribute will be a String with 3 acceptable values:
** oauth2: Indicating that the query parameters will be sent as usual following the oauth2 syntax.
** request: Indicating that the query will be sent as a jwt by value.
** request_uri: Indicating that the query will be sent as a reference to the jwt.

* The `authentication-request-format` attribute will specify if either `request` or the `request_uri` would be added to the auth request. This will be an optional attribute. The default value for this attribute will be set to `none`, indicating that neither request parameters are used and the query parameters are sent through the url.

** For multiple `secure-server` or `secure-deployment` resources using the same `realm` or `provider`, the `authentication-request-format` can be specified at the higher level resource.

** For multiple `secure-server` or `secure-deployment` resources using the same higher level resource, if the Request Object type is not the same, then the authentication-request-format` attribute can be set accordingly for the individual lower level resources.

* According to the https://openid.net/specs/openid-connect-core-1_0.html#JWTRequests[OIDC specs], only one of the two parameters can be specified at a time. If `request` is added, then `request_uri` MUST NOT be used in the same request. However, the user can choose to specify neither by setting `authentication-request-format` to `none`.

* The `request` and `request_uri` parameters MUST NOT be included in Request Objects.

* The Request Object MAY be signed or unsigned (plaintext) and can be specified by value or by reference. The user can specify the algorithm used to sign the JWT request using the `request-object-signing-algorithm` attribute which will also be added to the resources specified above.

** The values for `request-object-signing-algorithm` attribute are of type `String`. Default value for this attribute would be `none`, specifying that the request would be sent as a plaintext. The default value of `request-object-signing-algorithm` is `none`. The signing algorithm specified must be one of the signing algorithms accepted by the OpenID provider.

* The request object may also be encrypted. To specify that the request parameter will be encrypted, the user needs to specify the relevant algorithms using `request-object-encryption-algorithm` and `request-object-content-encryption-algorithm`.

** The values for the `request-object-encryption-algorithm` and the `request-object-content-encryption-algorithm` attributes are of type `String`. The default value for the attributes are null, which specifies that the request object will not be encrypted.

** The request object will only be encrypted if both `request-object-encryption-algorithm` and `request-object-content-encryption-algorithm` are specified. The values for these attributes must be part of the encryption algorithms and enc values supported by the OpenID provider.

** By value: The `request` parameter is added to the query and its value is the Request Object itself. The entire Request_URI MUST NOT exceed 512 ASCII characters.

** The request string can be added to the auth request by adding the whole string:

```
https://idsvr.example.com/oauth/v2/oauth-authorize?
&client_id=client-one
&response_type=code
&scope=openid
&request=y9Lqv4fCp6Ei-u2-ZCKq83YvbFEk6JMs...
```
** By reference: This is useful when the `request` string is too large and a number of other https://openid.net/specs/openid-connect-core-1_0.html#RequestUriRationale[reasons]. In this case, the Request Object is passed as a reference parameter string using the `request_uri` parameter. The value references the Request Object, which the Provider can use to download the Request Object itself.

** When included in the auth request, the request_uri would be specified as:

```
https://server.example.com/authorize?
response_type=code%20id_token
&client_id=s6BhdRkqt3
&request_uri=https%3A%2F%2Fclient.example.org%2Frequest.jwt
%23GkurKxf5T0Y-mnPFCHqWOMiZi4VS138cQO_V7PZHAdM
&state=af0ifjsldkj&nonce=n-0S6_WzA2Mj
&scope=openid
```

** The base64-encoded SHA-256 hash `23GkurKxf5T0Y-mnPFCHqWOMiZi4VS138cQO_V7PZHAdM` will allow the provider to cache the token for future use. It is a hash of the contents of the Request Object.

* According to the OpenID docs, if the same parameter exists both in the Request Object and the OAuth Authorization Request parameters, the parameter in the Request Object is used.

* The feature must deal with cases where the OpenId Provider does not support request parameters by recognizing `request_not_supported` error and dealing with it accordingly.

* It should be possible to specify that these parameters should be included in the Authentication Request via deployment configuration using the `oidc.json` file inside the `WEB-INF` directory of the web application and `elytron-oidc-client` subsystem configuration.

The `request` attribute is specified through the deployment configuration as follows:
```
{
"client-id" : "myclient",
"provider-url" : "${env.OIDC_PROVIDER_URL:http://localhost:8080}/realms/myrealm",
"public-client" : "true",
"authentication-request-format" : "request",
"principal-attribute" : "preferred_username",
"ssl-required" : "EXTERNAL"
}
```
The `request` attribute is specified through the `elytron-oidc-client` subsystem as follows:
```
/subsystem=elytron-oidc-client/secure-deployment:add(client_id=myclient, provider-url="http://localhost:8090/", authentication-request-format="request")
```

The request attribute is specified through the deployment configuration as follows:
```
{
"client-id" : "myclient",
"provider-url" : "${env.OIDC_PROVIDER_URL:http://localhost:8080}/realms/myrealm",
"public-client" : "true",
"authentication-request-format" : "request_uri",
"principal-attribute" : "preferred_username",
"ssl-required" : "EXTERNAL"
}
```
The `request` attribute is specified through the `elytron-oidc-client` subsystem as follows:
```
/subsystem=elytron-oidc-client/secure-deployment:add(client_id=myclient, provider-url="http://localhost:8090/", authentication-request-format="request_uri")
```

* For signed and encrypted request objects, we must need to use a private key, whose corresponding public key and certificate must be communicated with the OpenID provider. The public key is communicated to the OpenID provider using the admin console of the OpenID provider (i.e. Keycloak). And the same keypair is added to the deployment settings using existing attributes `client-keystore`, `client-keystore-password`, `client-key-password`, which are available under the `secure-deployment`, `secure-server`, `realm` and provider resources. Additionally, `client-key-alias` and `client-keystore-type` attributes will be added to these resources for additional information about the keystore.

** The key specified during WildFly server configuration and openID client configuration must be the same for the provider to read the contents of the Request Object.

=== Nice-to-Have Requirements

N/A

=== Non-Requirements

N/A

== Backwards Compatibility

N/A

=== Default Configuration

By default, neither `request` or `request_uri` would be specified.

== Test Plan

* WildFly Elytron Tests: Test cases implemented for functionality.
* WildFly Testsuite: Test cases will be added to check for subsystem parsing.
** Additional integration tests will be added to test the full functionality of the `elytron-oidc-subsystem` when `request` and `request_uri` are configured.
** Tests will be performed using signed, unsigned, encrypted and plaintext JWT requests, with the request specified both by value and by reference.

== Community Documentation
Documentation for the new `request` and `request_uri` attributes will be added to https://github.com/wildfly/wildfly/blob/main/docs/src/main/asciidoc/_admin-guide/subsystem-configuration/Elytron_OIDC_Client.adoc[Elytron OpenID Connect Client Subsystem Configuration].

0 comments on commit 9491f5b

Please sign in to comment.