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

fix: show client secret input for PKCE auth code flow #8268

Merged

Conversation

Phoosha
Copy link
Contributor

@Phoosha Phoosha commented Oct 31, 2022

Description

Show the client secret input always (for the authorization code flow) regardless of the PKCE flag.

Closes #7913

Motivation and Context

PKCE and Client Secrets are allowed to coexist and neither is designed as a replacement for the other. [1] It is wrong to assume that a client secret must not or cannot be used in combination with PKCE. Quite the opposite, when possible both PKCE and client secret should be used. [2] So the premises of #6290 and #8146 are not correct.

Admittedly, for users of the PKCE mechanism WITHOUT a client secret it might be a minor nuisance to see the client secret input in the Swagger UI. But they can just leave it empty. On the other hand, for users of the PKCE mechanism WITH a client secret it is more than just a nuisance if the client secret input is not shown. The Swagger UI becomes unusable for them (unless they've set a default value for the client secret, which will be used hiddenly without being shown to the user).

Therefore the right course of action for now would be to revert #7438 to show the client secret input always regardless of PKCE. In the future a new flag could be introduced to hide the client secret input regardless of the PKCE flag.

[1] https://oauth.net/2/pkce/
[2] https://www.oauth.com/oauth2-servers/pkce/

How Has This Been Tested?

If the flag usePkceWithAuthorizationCodeGrant is set and the loaded API spec contains OAuth2 with the authorization code flow (i.e. AUTH_FLOW_ACCESS_CODE), the client secret input appears and an access token can be obtained from an authorization server requiring both PKCE and client secret.

Screenshots (if appropriate):

image

Checklist

My PR contains...

  • No code changes (src/ is unmodified: changes to documentation, CI, metadata, etc.)
  • Dependency changes (any modification to dependencies in package.json)
  • Bug fixes (non-breaking change which fixes an issue)
  • Improvements (misc. changes to existing features)
  • Features (non-breaking change which adds functionality)

My changes...

  • are breaking changes to a public API (config options, System API, major UI change, etc).
  • are breaking changes to a private API (Redux, component props, utility functions, etc.).
  • are breaking changes to a developer API (npm script behavior changes, new dev system dependencies, etc).
  • are not breaking changes.

Documentation

  • My changes do not require a change to the project documentation.
  • My changes require a change to the project documentation.
  • If yes to above: I have updated the documentation accordingly.

Automated tests

  • My changes can not or do not need to be tested.
  • My changes can and should be tested by unit and/or integration tests.
  • If yes to above: I have added tests to cover my changes.
  • If yes to above: I have taken care to cover edge cases in my tests.
  • All new and existing tests passed.

@Phoosha Phoosha marked this pull request as draft November 2, 2022 09:33
PKCE and Client Secrets are allowed to coexist and neither is designed
as a replacement for the other. [1] It is wrong to assume that a client
secret must not or cannot be used in combination with PKCE. Quite the
opposite, when possible both PKCE and client secret should be used. [2]
So the premises of swagger-api#6290 and swagger-api#8146 are not correct.

Admittedly, for users of the PKCE mechanism WITHOUT a client secret it
might be a minor nuisance to see the client secret input in the Swagger
UI. But they can just leave it empty. On the other hand, for users of
the PKCE mechanism WITH a client secret it is more than just a nuisance
if the client secret input is not shown. The Swagger UI becomes unusable
for them (unless they've set a default value for the client secret,
which will be used hiddenly without being shown to the user).

Therefore the right course of action for now would be to revert swagger-api#7438 to
show the client secret input always regardless of PKCE. In the future a
new flag could be introduced to hide the client secret input regardless
of the PKCE flag.

[1] https://oauth.net/2/pkce/
[2] https://www.oauth.com/oauth2-servers/pkce/
@Phoosha Phoosha force-pushed the ft/7913-show-client-secret-input-for-pkce branch from 3d22ec1 to a789562 Compare November 2, 2022 09:51
@Phoosha Phoosha marked this pull request as ready for review November 2, 2022 09:52
@Phoosha
Copy link
Contributor Author

Phoosha commented Nov 2, 2022

Fixed tests and while at it added a little documentation.

@tim-lai tim-lai merged commit 7b0ac1a into swagger-api:master Nov 4, 2022
@tim-lai
Copy link
Contributor

tim-lai commented Nov 4, 2022

@Phoosha PR merged! It was very helpful providing supporting documentation, and it should be helpful to anyone who is looking for clarify on this topic. Thanks for the contribution!

@MaNa2k
Copy link

MaNa2k commented Jan 31, 2023

Hi, I understand the problem some users have, that they need both options. But in my case it's not necessary to show the 'client_secret' field. Is there any ad-hoc solution to hide the field, or at least until there's a proper way?
I have tried injection css, but i didnt get it to work.

@Phoosha
Copy link
Contributor Author

Phoosha commented Feb 2, 2023

Hi, I understand the problem some users have, that they need both options. But in my case it's not necessary to show the 'client_secret' field. Is there any ad-hoc solution to hide the field, or at least until there's a proper way? I have tried injection css, but i didnt get it to work.

Hi @MaNa2k, as far as I'm aware there was no solution. In general I believe it's not an issue to show the field because it can just be left empty. But I don't know your exact use case and do understand, it can be confusing to prompt users for something which in your case they do not have to and should not provide. Anyway, I guess without changes at the Swagger UI side your best bet is the CSS injection you already tried.

As far as the Swagger UI side is concerned, I'm just someone who contributed this fix. So if you need this feature, I suggest you take a look at the Contributing guide, which explains how to open issues or contribute code.

For a quick fix I would add a flag to initOAuth, e.g. hideClientSecretInput: boolean (or hideClientSecretInput: 'authorizationCode' | 'clientCredentials' | ...) similar to the current usePkceWithAuthorizationCodeGrant. This would also work for my use case because I could just leave the flag at its default of false.

For a cleaner, more flexible solution I'd use the specification extensions of the OpenAPI spec to indicate the requirement of PKCE and Client Secret individually per security scheme (instead of globally for all security schemes). Interestingly that's also the approach chosen by Redocly with an x-usePkce extension. That's in my opinion a much more appropriate solution. The disadvantage is, that it might need additional changes to projects generating the OpenAPI spec.

@MaNa2k
Copy link

MaNa2k commented Feb 3, 2023

Thanks for your replay. We authenticate our users via Microsoft Login page which validates user against an App Registration in Azure, which is why we don't need to show those fields

I got a quick fix working yesterday for my problem. Basically injecting a custom CSS, in which I hide those fields.
In this sample, I'm hiding both client_id and client_secret

Step 1

  • Add the following lines in your app.UseSwaggerUI
  • Also don't forget to add the app.UseStaticFiles
app.UseSwaggerUI(c =>
{
      c.InjectStylesheet("/swagger/custom.css");
      c.OAuthClientId(builder.Configuration["AzureAd:ClientId"]);
      c.OAuthUsePkce();
});
app.UseStaticFiles();

Step 2

Make the following folders and file in your project,
wwwroot\swagger\custom.css

image

Remember, you must have that globe icon on your wwwroot folder, otherwise it doesn't seem to work for me.
I needed to clean my solution then restart visual studio to make it work.

Step 3

Put this CSS code inside your custom.css

label[for="client_id"] {
    display: none;
}

label[for="client_secret"] {
    display: none;
}

#client_secret {
    display: none
}

#client_id {
    display: none;
}

Now both the fields client_id, client_secret and their labels will be hidden from the Swagger Auth modal.

@Rasmus715
Copy link

Rasmus715 commented Dec 15, 2023

You should've provided the option to configure the field presence in the first place rather than reverting other's people changes.

@relu91
Copy link

relu91 commented Mar 18, 2024

Admittedly, for users of the PKCE mechanism WITHOUT a client secret it might be a minor nuisance to see the client secret input in the Swagger UI. But they can just leave it empty.

You should've provided the option to configure the field presence in the first place rather than reverting other's people changes.

I was hoping that leaving the clientSecret empty would be understood by swagger-ui to not show the field. Having a flag to explicitly say it would be good too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

authorization_code flow with PKCE does not allow entering a client secret
5 participants