Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rebase from upstream #18

Open
wants to merge 101 commits into
base: master
Choose a base branch
from
Open

Conversation

eric-hostalery
Copy link

No description provided.

gregmolnar and others added 30 commits January 4, 2019 18:03
* Add logout phase

* Avoid to make a discover for each other_phase call

* avoid using match when MatchData is not used
* fix: Allow rails applications to handle state mismatch

* Addressed reviewer-bot
* Allow state method to receive env

I have a state algorithm that requires access to values in env. This change allows it to receive that reference in a backwards compatible way and brings the state method in line with the setup method.

* Add parenthesis and eliminate ternary operator

* Add test for dynamic state generation
* Set default OmniAuth name to openid_connect

If no name option is given, OmniAuth will attempt to translate
OmniAuth::Strategies::OpenIDConnect to openidconnect. This led
to confusion for a number of GitLab users who omitted the name
argument because /users/auth/openid_connect did not match
/users/auth/openidconnect.

* Fix tests to use openid_connect
It's used by things like Dependabot to find commit diffs, changelogs, etc., and currently points to the wrong place.
* Add support for response_type id_token

* Simplify the response_type validation

* Remove unnecessary statements from README
Apparently it never worked as a symbol, although it was mentioned in README
* Cast response_type to string when checking if it is set in params

Rails will provide params with indifferent access but that's not guaranteed with other frameworks.
Omniauth sets keys as string, e.g. hash[field] = request.params[field.to_s]

* Define a normalized response_type method for use in string comparisons
* The complete id_token is now a part of the hash that is returned to the application
* Bugfix: Redefining env method for Strategy class caused race condition in test execution
stanhu and others added 27 commits November 30, 2022 13:42
In non-standard OpenID Connect providers, such as Azure B2C, discovery
does not work because the discovery URL does not match the issuer field.
If a JWKS URI is provided when discovery is disabled, we should make an
HTTP request for the keys and use the response.

Closes #72
When an OpenID provider such as Keycloak is configured to use the
HS256 algorithm to sign JSON Web Tokens (JWTs), previously logins
would fail with an obscure error:

```
JSON::JWS::UnexpectedAlgorithm (no implicit conversion of OpenSSL::PKey::RSA into String)
```

The HS256 algorithm relies on a shared secret between the client and
the server, and this secret is not in the list of JSON Web Key Set
(JWKS) that is typically retrieved via a public endpoint during OpenID
Discovery.

The error was happening because decoding a HS256-signed JWT with
public key RSA key will fail. We should only attempt to decode with
the configured `client_options.secret`.

To do this, we need to decode the JWT to examine the header to
determine how it was signed. For example:

```json
{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "RrHQomcBaw2FJZ9Q5skkNaPC6sHJFLUAf4uoeaItDPE"
}
```

This indicates that the payload was signed with `RS256`, a public key
algorithm.

Once we know the algorithm used to decode, we can determine which key
to use. For public key algorithms such as `RS256`, we use the
JWKS. For signature-based algoriths such as `HS256`, we use the
configured client secret.

This merge request also cleans up some technical debt. Previously we
didn't peek at the unverified JWT to determine the key ID (`kid`) that
the payload was signed with. If we got a `KidNotFound` exception from
the decoding, previously we couldn't tell whether this was happening
because we didn't have a matching key in JWKS, or whether the JWT
didn't have a `kid` to begin with. Now that we decode the header, we
can tell these cases apart. If the JWT has no `kid` and we get
`KidNotFound` from decoding, we know the server didn't supply the
right set of keys. Otherwise, we can just use try key until we find
one that works.

Relates to
https://gitlab.com/gitlab-org/ruby/gems/gitlab-omniauth-openid-connect/-/issues/1

This is part of the effort to upstream changes in the GitLab fork:
https://gitlab.com/gitlab-org/ruby/gems/gitlab-omniauth-openid-connect/-/issues/5.
If a client is configured for a specific `client_signing_alg` but the
JWT returns a different algorithm, fail the callback immediately to
prevent some insecure downgrade from happening.
When decoding a JWT with some error, we need to catch the right error:

`JSON::JWS::UnknownAlgorithm => `JSON::JWK::UnknownAlgorithm`
These versions reached end-of-life last year, so let's drop
support.
This fixes a regression in v0.7.0 where the JWKS response returns as a
Hash instead of a String due to the change in openid_connect modifying
the Faraday response handling.

This commit also improves the testing by using webmock instead of
stubbing the Farday response.

Closes #156
@eric-hostalery eric-hostalery added echoes/pillars: tech-value Changes intended at preserving our ability to evolve the software safely and effectively echoes/effort: XS Very low effort changes (M * 0.2) labels Jan 24, 2024
@eric-hostalery eric-hostalery self-assigned this Jan 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
echoes/effort: XS Very low effort changes (M * 0.2) echoes/pillars: tech-value Changes intended at preserving our ability to evolve the software safely and effectively
Projects
None yet