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

Missing payload.iss mapping in OpenIDAuthDriver when the oidc support authorization_response_iss_parameter_supported #18008

Closed
Romakita opened this issue Mar 31, 2023 · 0 comments · Fixed by #18009

Comments

@Romakita
Copy link
Contributor

Romakita commented Mar 31, 2023

Describe the Bug

Hello teams,

First thing, your cms is amazing! Great works.

I open this issue because I try to connect the CMS with a self hosted oidc server.
The oidc server is implemented using oidc-provider developed by panva
which is the same author of openid-client used by your openid. But I'm not able to login a user because your openid auth implementation is incomplete.

Let me explain the problem ;)

To Reproduce

The openid client get metadata with the /.well-known/openid-configuration to get all routes to get authorization url/token and to control the access_token delivered by the OIDC server.

One of the option returned by the well-known is authorization_response_iss_parameter_supported.

{
   "issuer":"http://localhost",
   "jwks_uri":"http://localhost/jwks",
   "authorization_response_iss_parameter_supported": true, /// this options enable an extra control from openid-client
   "authorization_endpoint":"http://localhost/authorize"
}

This option, enable a specific control performed by openid-client, during the callback (to get a token in exchange of the code). The ref code is here:

https://github.com/panva/node-openid-client/blob/main/lib/client.js#L415

And call this verify here in the OpenID Auth provider:

https://github.com/directus/directus/blob/main/api/src/auth/drivers/openid.ts#L132

tokenSet = await client.callback(
  this.redirectUrl,
  { code: payload['code'], state: payload['state'] },
  { code_verifier: payload['codeVerifier'], state: codeChallenge, nonce: codeChallenge }
);

But this control shouldn't be triggered if the iss is available in given parameters here:

{ code: payload['code'], state: payload['state'] },

From the OIDC spec, the iss is given at the same time with the code and state in the callback redirection:

http://localhost:8055/auth/login/clubmed/callback?code=code&state=state&iss=localhost

iss seems to be mandatory by openid-client. But the fix is pretty easy. adding the correct mapping solve the issue:

Here:

tokenSet = await client.callback(
  this.redirectUrl,
  { code: payload['code'], state: payload['state'], iss: payload['iss'] },
  { code_verifier: payload['codeVerifier'], state: codeChallenge, nonce: codeChallenge }
);

https://github.com/directus/directus/blob/main/api/src/auth/drivers/openid.ts#L134

and here:

 authResponse = await authenticationService.login(providerName, {
    code: req.query['code'],
    codeVerifier: verifier, 
    state: req.query['state'],
    iss: req.query['iss'],
});

https://github.com/directus/directus/blob/main/api/src/auth/drivers/openid.ts#L337

This addition, improve the security flow between an OIDC server and a directus cms instance.

I hope my fix suggestion will help you. I also make a PR to help you!

See you

Hosting Strategy

Self-Hosted (Docker Image)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
2 participants