2

We are trying to configure swagger in our .NET 6 API project so that it automatically retrieves the access_token from Azure token endpoint with "client credentials flow". Here is the configuration part in startup.cs

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "register_api", Version = "v1" });
    c.SchemaFilter<EnumSchemaFilter>();

    var jwtSecurityScheme = new OpenApiSecurityScheme
    {
        Type = SecuritySchemeType.OAuth2,
        Scheme = "bearer",
        BearerFormat = "JWT",
        Flows = new OpenApiOAuthFlows
        {
            ClientCredentials = new OpenApiOAuthFlow
            {
                TokenUrl = new Uri(@"https://login.microsoftonline.com/512024a4-8685-4f03-8086-14a61730e818/oauth2/v2.0/token"),
                Scopes = new Dictionary<string, string>() { { @"api://e92b626c-f5e7-422b-a8b2-fd073b68b4a1/.default", ".default" } }
            }
        }
    };

    c.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, jwtSecurityScheme);

    c.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        { jwtSecurityScheme, new string[] { @"api://e92b626c-f5e7-422b-a8b2-fd073b68b4a1/.default" } }
    });
}

It looks as follows when the user clicks the "Authorize" button the first time. But then, after entering the client_id and client_secret and clicking Authorize button, it shows up the message "Auth Error TypeError: Failed to fetch"

enter image description here

There is something weird with the request that is sent to the token endpoint. The payload includes just the grant_type and the scope. But the client_id and client_secret are base64 encoded and sent in Authorization header:

enter image description here

Is it the reason that the Azure token endpoint refuses to generate the access_token? I have used the same token endpoint and succeeded to get token with postman, but I included all the parameters in the payload.

If that is the case, is it possible to change the configuration of Swagger so that client_id and client_secret are sent in the payload instead (together with the grant_type and the scope) ?

Przemek
  • 795
  • 8
  • 17
  • 3
    When you see the "Failed to fetch" error, what is the error message on the Console tab of the browser dev tools? Could be a CORS issue. – Helen Dec 15 '21 at 15:14
  • @Helen Hi, looks like it is because CORS issue. Here is the message: Access to fetch at 'https://login.microsoftonline.com/512024a4-8685-4f03-8086-14a61730e817/oauth2/v2.0/token' from origin 'https://localhost:44332' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. Should it be configured as part of Swagger? Do you know how? – Przemek Dec 15 '21 at 16:04
  • Does this answer your question? [Enabling CORS on Azure Active Directory](https://stackoverflow.com/q/52839055/113116) Specifically this part - _"The way to acquire tokens from a front-end JS app is to use Implicit Grant Flow or Authorization Code flow with PKCE. Or if you do need an app-only token, then you must do the request you tried from a back-end application."_ – Helen Dec 15 '21 at 16:28
  • Thanks for your response but the answer in the link is not really relevant here because we use Swagger in dotnet core. Swagger itself is responsible for creation of the GUI OpenAPI frontend that interacts with Azure AD token endpoint to retrieve the token. I cannot change the flow for this API to implicit flow because it cannot be applied to backed APIs. – Przemek Dec 15 '21 at 16:47
  • 1
    This issue is discussed in the Swagger UI issue tracker: https://github.com/swagger-api/swagger-ui/issues/6081. According to the comments, a possible solution could be to use the `requestInterceptor` to either a) remove the `X-Requested-With` header from requests; or b) proxy the requests through a CORS proxy ([example](https://github.com/swagger-api/swagger-ui/issues/1888#issuecomment-173179594)). – Helen Dec 15 '21 at 17:11
  • Thanks again. Looks like this would require to buy or set up a proxy server. I prefer to stick to Postman and bearer token in stead that already works in my scenario. Easier then proxy server as far as I am concerned. – Przemek Dec 16 '21 at 08:16
  • 1
    `requestInterceptor` is not a proxy server, it's a [piece of JavaScript](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/#use-client-side-request-and-response-interceptors) added to Swagger UI config that can mutate outgoing requests, e.g. add or remove headers or change the request URL. You can try using it to remove the `X-Requested-With` header from requests. Maybe this will help avoid the CORS issue. – Helen Dec 16 '21 at 08:48
  • I will look at it. :) – Przemek Dec 16 '21 at 09:10
  • Anyone has find a solution? – Davide Boldrin May 12 '23 at 15:17

0 Answers0