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

Supporting Azure AD OAuth 2.0 Client Credentials Grant Flow #5223

Open
gustavnyberg opened this issue Mar 7, 2019 · 7 comments
Open

Supporting Azure AD OAuth 2.0 Client Credentials Grant Flow #5223

gustavnyberg opened this issue Mar 7, 2019 · 7 comments

Comments

@gustavnyberg
Copy link

gustavnyberg commented Mar 7, 2019

Azure AD OAuth 2.0 Client Credentials Grant Flow (https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow)

Content & configuration

Swagger/OpenAPI definition: 2.0

Swashbuckle.AspNetCore 4.0.1

Swagger-UI configuration options:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc(resourceName, new Info {Title = urn});
c.CustomSchemaIds(i => i.FullName);
c.AddSecurityDefinition
(
oAuth2SecurityDefinitionName,
new OAuth2Scheme
{
Type = oAuth2,
Flow = application,
TokenUrl = tokenUrl,
Scopes = new Dictionary<string, string> { { oAuth2SecurityDefinitionName, userImpersonation } }
}
);
c.AddSecurityRequirement(new Dictionary<string, IEnumerable> {{oAuth2SecurityDefinitionName, new[] {userImpersonation}}});
});

SwaggerUI({
c.OAuthClientId(clientId);
c.OAuthClientSecret(clientSecret);
c.OAuthRealm(uri);
c.OAuthAppName(resourceName);
c.OAuthScopeSeparator(value: " ");
c.SwaggerEndpoint($"/swagger/{resourceName}/swagger.json", resourceName);
})

Is your feature request related to a problem?

The Swagger UI OAuth2 Application Flow does not support the Azure AD OAuth 2.0 Client Credentials Grant Flow for the V1 endpoint.

This is due to two things:

  1. The client_id and client_secret needs to be sent in the request body, instead of a Basic Auth Header, which now is the case.

  2. Microsoft also has an other key/value that needs to be included in the request body, namely 'resource' which is either the AppId (Guid) or the Uri (e.g. https://the-azure-resource-display-name.azurewebsites.net") for the Azure Resource, which is likely also the OAuthRealm.

  3. I have not been able to test if you also get both Delegated Permissions (aka Scopes, e.g. user_impersonation) and the Application Permissions (aka Roles) in the Token, since I don't come that far, but it needs to be ensured as well.

Describe the solution you'd like

Either you implement a separate hard coded flow for this like the ones you already have:

swagger-ui/src/core/plugins/auth/actions.js

export const authorizeApplication = ( auth ) => ( { authActions } ) => {
let { schema, scopes, name, clientId, clientSecret } = auth
let headers = {
Authorization: "Basic " + btoa(clientId + ":" + clientSecret)
}
let form = {
grant_type: "client_credentials",
scope: scopes.join(scopeSeparator)
}

Add something like this:

export const authorizeAzureActiveDirectoryApplication = ( auth ) => ( { authActions } ) => {
let { schema, scopes, name, clientId, clientSecret } = auth
let form = {
grant_type: "client_credentials",
client_id : "your-client-id"
client_secret : "your-client-secret"
resource : "appId/appUri"
scope: scopes.join(scopeSeparator)
}

Or a more generic solution would be to add configuration for this.

You have done something like this in the Swagger UI OAuth2 Password Flow, where you can choose whether to send credentials in the Header or the Body.

Preferably this could also be done directly in the StartUp configuration looking something like this:

SwaggerUI({
c.OAuthClientId(clientId);
c.OAuthClientSecret(clientSecret);
c.SendOAuthClientCredentialsIn(BasicAuthHeader/RequestBody)
c.OAuthRealm(uri);
c.OAuthAppName(resourceName);
c.OAuthScopeSeparator(value: " ");
c.OAuthAdditionalQueryStringParams(new Dictionary<string, string> {});
c.OAuthAdditionalRequestBodyParams(new Dictionary<string, string> {{"resource", uri}});
c.SwaggerEndpoint($"/swagger/{resourceName}/swagger.json", resourceName);
})

Describe alternatives you've considered

Using the implicit flow, which works, but then requires that you configure your Azure Resource to allow the Implicit Flow, that you have a User and not just an Application, that the User has the same access, scopes and roles as the Client Application has as well as that and that user impersonation is allowed.

Additional context

Azure AD OAuth 2.0 Client Credentials Grant Flow (https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow) is the recommended way of doing service to service calls using client credentials (shared secret or certificate) in Azure according to Microsoft and it would be great to be able to use the same Auth process in Swagger that is used in the actual flow.

@ceuk
Copy link

ceuk commented Apr 8, 2020

Hi @gustavnyberg did you ever find a workaround for this that doesn't require awarding users the same permissions as the app?

@mtmjansen
Copy link

I've the same problem.
Can't set the resource for AzureAD Client credentials flow

@mtmjansen
Copy link

Maybe Microsoft should provide a OpenApi Extension for Credentials Flow resource parameter.
Current extensions are mostly action based: https://docs.microsoft.com/en-us/connectors/custom-connectors/openapi-extensions

@jbogard
Copy link

jbogard commented Jul 9, 2021

Just hit this today, it really comes down to being able to configure how the credentials are passed in for the client credentials flow - either the header or the body. Postman supports this today, with a configuration option to send client credentials in the body or as a Basic Auth header:
image

@NicoaraBogdan
Copy link

Still no support ..

@rebelzach
Copy link

rebelzach commented Sep 27, 2023

It's wild that this still hasn't been addressed.

@bedadiggelmann
Copy link

I am facing the same issue with Azure B2C as token provider. Client id and client secret need to be passed in the body. See: Azure B2C - Obtain an access token
Any updates on this issue?

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

No branches or pull requests

8 participants