最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

asp.net core - How do I configure Scalar to authenticate through Entra? - Stack Overflow

programmeradmin2浏览0评论

I have a web app where the front-end authenticates using Microsoft Entra and uses the bearer token from that to authenticate with my backend APIs.

I have just removed Swagger / SwaggerUI from my app and replaced it with Microsoft's OpenAPI package and Scalar's ASP.NET package; Swagger wasn't fully functional, so I decided to upgrade and spend the time trying to get things working with the modern alternatives.

Scalar starts up and allows me to view all the backend APIs and send requests, but it doesn't know about the authentication so every request to an authenticated API (there are also a few that allow anonymous requests) returns a 401 response.

Can I configure OpenAPI / Scalar so that it knows which APIs require authentication and to authenticate the user properly allowing me to test my authenticated APIs.

At a previous job someone had configured SwaggerUI to do this, where clicking a couple of buttons would trigger authentication with Entra and then authenticate with the APIs we were testing; however, I don't actually know how they did this. This is the functionality I'd like to achieve through Scalar.

This is a personal (non-commercial) site I'm building for a club I'm a member of, for fun (no payment).

I'm using an ASP.NET Core 9 Web API backend and a Blazor WebAssembly frontend (which does authenticate properly).

I can't find any guides on how to do this, so I'm not sure if it's not possible or just too new to have many guides in general.

Update: After following the answer by Aaron FC below, I got Scalar authenticating with Entra, but I still get 401 errors with the error Bearer error="invalid_token", error_description="The issuer '(null)' is invalid" in the header. Disabling the issuer checks, I get Bearer error="invalid_token", error_description="The signature key was not found"

My OpenAPI config is now:

builder.Services.AddOpenApi(options =>
{
    options.AddDocumentTransformer((document, context, cancellationToken) =>
    {
        document.Components ??= new OpenApiComponents();

        document.Components.SecuritySchemes.Add("oauth", new OpenApiSecurityScheme
        {
            Type = SecuritySchemeType.OAuth2,
            Flows = new OpenApiOAuthFlows
            {
                AuthorizationCode = new OpenApiOAuthFlow
                {
                    AuthorizationUrl = new Uri(".0/authorize"),
                    TokenUrl = new Uri(".0/token"),
                    Scopes = new Dictionary<string, string>
                    {
                        {builder.GetConfiguration("AzureAd:Scopes"), "Data Access"}
                    },
                    // To allow Scalar to select PKCE by Default
                    // valid options are 'SHA-256' | 'plain' | 'no'
                    Extensions = new Dictionary<string, IOpenApiExtension>()
                    {
                        ["x-usePkce"] = new OpenApiString("SHA-256")
                    }
                }
            }
        });

        return Task.CompletedTask;
    });
});

I have a web app where the front-end authenticates using Microsoft Entra and uses the bearer token from that to authenticate with my backend APIs.

I have just removed Swagger / SwaggerUI from my app and replaced it with Microsoft's OpenAPI package and Scalar's ASP.NET package; Swagger wasn't fully functional, so I decided to upgrade and spend the time trying to get things working with the modern alternatives.

Scalar starts up and allows me to view all the backend APIs and send requests, but it doesn't know about the authentication so every request to an authenticated API (there are also a few that allow anonymous requests) returns a 401 response.

Can I configure OpenAPI / Scalar so that it knows which APIs require authentication and to authenticate the user properly allowing me to test my authenticated APIs.

At a previous job someone had configured SwaggerUI to do this, where clicking a couple of buttons would trigger authentication with Entra and then authenticate with the APIs we were testing; however, I don't actually know how they did this. This is the functionality I'd like to achieve through Scalar.

This is a personal (non-commercial) site I'm building for a club I'm a member of, for fun (no payment).

I'm using an ASP.NET Core 9 Web API backend and a Blazor WebAssembly frontend (which does authenticate properly).

I can't find any guides on how to do this, so I'm not sure if it's not possible or just too new to have many guides in general.

Update: After following the answer by Aaron FC below, I got Scalar authenticating with Entra, but I still get 401 errors with the error Bearer error="invalid_token", error_description="The issuer '(null)' is invalid" in the header. Disabling the issuer checks, I get Bearer error="invalid_token", error_description="The signature key was not found"

My OpenAPI config is now:

builder.Services.AddOpenApi(options =>
{
    options.AddDocumentTransformer((document, context, cancellationToken) =>
    {
        document.Components ??= new OpenApiComponents();

        document.Components.SecuritySchemes.Add("oauth", new OpenApiSecurityScheme
        {
            Type = SecuritySchemeType.OAuth2,
            Flows = new OpenApiOAuthFlows
            {
                AuthorizationCode = new OpenApiOAuthFlow
                {
                    AuthorizationUrl = new Uri("https://login.microsoftonline/common/oauth2/v2.0/authorize"),
                    TokenUrl = new Uri("https://login.microsoftonline/common/oauth2/v2.0/token"),
                    Scopes = new Dictionary<string, string>
                    {
                        {builder.GetConfiguration("AzureAd:Scopes"), "Data Access"}
                    },
                    // To allow Scalar to select PKCE by Default
                    // valid options are 'SHA-256' | 'plain' | 'no'
                    Extensions = new Dictionary<string, IOpenApiExtension>()
                    {
                        ["x-usePkce"] = new OpenApiString("SHA-256")
                    }
                }
            }
        });

        return Task.CompletedTask;
    });
});
Share Improve this question edited 7 hours ago Mog0 asked Feb 16 at 14:39 Mog0Mog0 2,1273 gold badges25 silver badges48 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

I struggled with finding documentation too but eventually came across a few things that pointed me in the right direction (linked below). You have to add a DocumentTransformer -> SecuritySchema using the AddOpenApi options:

Configure Open API

builder.Services.AddOpenApi(o =>
{
    o.AddDocumentTransformer((document, _, _) =>
    {
        document.Components ??= new OpenApiComponents();
        
        document.Components.SecuritySchemes.Add("oauth", new OpenApiSecurityScheme
        {
            Type = SecuritySchemeType.OAuth2,
            Flows = new OpenApiOAuthFlows
            {
                AuthorizationCode = new OpenApiOAuthFlow
                {
                    AuthorizationUrl = new Uri("<your-app-auth-endpoint>"),
                    TokenUrl = new Uri("<your-app-token-endpoint>"),
                    Scopes = new Dictionary<string, string>
                    {
                        {"api://<client-id>/data.read", "Read Data"}
                    },
                    // To allow Scalar to select PKCE by Default
                    // valid options are 'SHA-256' | 'plain' | 'no'
                    Extensions = new Dictionary<string, IOpenApiExtension>()
                    {
                        ["x-usePkce"] = new OpenApiString("SHA-256")
                    }
                    
                }
            }
        });
        
        return Task.CompletedTask;
    });
});

You can find the authorize/token endpoints by going to your Entra Admin Center -> Applications -> App Registrations -> (Selecting Your App) -> Endpoints (top banner at the time of writing) and then I used the OAuth 2.0 auth/token endpoints that should look something like:

https://login.microsoftonline/<directory-id>/oauth2/v2.0/authorize https://login.microsoftonline/<directory-id>/oauth2/v2.0/token

Wire-up Scalar with Defaults:

app.MapScalarApiReference(c =>
{
    c.WithOAuth2Authentication(o =>
    {
        o.ClientId = "<client-id>";
        o.Scopes = ["api://<client-id>/data.read"];
    });
});

We had to add a scope for our API app registration as using just User.Read did not work. You can do this by going to your app registration -> Expose an API and then adding a scope that will usually look something like: api://<client-id>/<scope-name>

You'll also want to register the redirect url for your client app registration in Entra as the url of the scalar client. In most cases it's something like https://localhost:<some-port>/scalar/v1

Once this is all configured, you can spin up the Scalar UI. There should be an Authentication box at the top with an Auth Type dropdown. You can select oauth and then ensure PKCE/Scopes are selected and click Authorize.

Additional Context

We currently have two App Registrations in Entra. One is for our Frontend Angular SPA and the other is for our .NET Web API. The client-id we used was from the frontend App Registration while the scopes came from the backend App Registration.

Helpful Docs

Customize OpenAPI Documents

Scalar .NET Integration

IDX10511 Errors

SO Post 1

SO Post 2

发布评论

评论列表(0)

  1. 暂无评论