使用 Swagger UI 进行 OAuth 2.0 身份验证

问题描述 投票:0回答:1

我有一个 ASP.NET Core Web Api 项目,其中包含以下 program.cs 文件:

    using (var scope = temporaryProvider.CreateScope())
        {
            var dataverseUtilityService = scope.ServiceProvider.GetRequiredService<IDataverseUtilityService>();

            // Fetch tenantId and clientId from DataverseUtilityService
            var configuration = dataverseUtilityService.GetConfiguration();
            var tenantId = configuration.msys_AzureTenantId;
            var clientId = configuration.msys_AzureClientId;

            // Swagger configuration with OAuth2 using Authorization Code Flow and client secret
            builder.Services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });

                // Define OAuth2 Authorization Code Flow (without PKCE)
                options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
                {
                    Type = SecuritySchemeType.OAuth2,
                    Description = "OAuth 2.0 Authorization Code Flow (with client secret)",
                    Flows = new OpenApiOAuthFlows
                    {
                        AuthorizationCode = new OpenApiOAuthFlow
                        {
                            AuthorizationUrl = new Uri($"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize"),
                            TokenUrl = new Uri($"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token"),
                            Scopes = new Dictionary<string, string>(StringComparer.Ordinal)
                            {
                                { $"api://{clientId}/access_the_api/.default", "Access API" },
                            },
                        },
                    },
                });

                options.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id = "oauth2",
                            },
                            Scheme = "oauth2",
                            Name = "oauth2",
                            In = ParameterLocation.Header,
                        },
                        new List<string> { $"api://{clientId}/access_the_api/.default" }
                    },
                });
            });
        }

        // Build the app after adding Swagger configuration
        var app = builder.Build();

        // Enable Swagger UI and Swagger endpoint in all environments
        app.UseSwagger();
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "MedlemssystemApi V1");
            c.OAuth2RedirectUrl(url: "https://app-dev-medlemssystemapi.azurewebsites.net/swagger/oauth2-redirect.html");
        });

        // Basic middleware for all environments
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        // Map controllers and APIs
        app.MapControllers();

        // Run the app
        app.Run();

我的应用程序注册身份验证设置如下:

enter image description here

enter image description here

并手动设置以下范围:

enter image description here

当我尝试在 Swagger UI 中进行身份验证时出现问题:

enter image description here

出现以下错误:

auth errorError: response status is 400, error: invalid_request, description: AADSTS9002326: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type. Request origin: 'https://app-dev-medlemssystemapi.azurewebsites.net'. Trace ID: eeb5797b-7c22-4162-a2f9-ae086eef1300 Correlation ID: 5a6cbca2-73c5-4ad8-8352-58d80ad6d47f Timestamp: 2024-09-19 14:41:59Z

它似乎总是期望重定向 URL 配置为单页应用程序?是否可以让身份验证流程与 Web 应用程序配置一起使用?.

authentication oauth-2.0 azure-active-directory swagger asp.net-core-webapi
1个回答
0
投票

我为 ASP .NET Core API 创建了一个示例 Swagger UI 授权,并且已成功授权,没有任何错误。

它似乎总是希望将重定向网址配置为单页应用程序?

是的,你是对的。唯一的方法是在

Single Page Application
平台中配置重定向URI。如果你使用Web平台,也会抛出同样的错误。

enter image description here

为了避免该错误,我将授权 URL、令牌和范围放在

appsettings.json.
而不是
program.cs
中。

  • 我使用了以下范围,
"Scope": "api://<API-appregistration-client-id/access_as_user",

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "microsoft.onmicrosoft.com",
    "TenantId": "<tenant-id>",
    "ClientId": "<client-id",
    "CallbackPath": "/signin-oidc",
    "Scope": "access_as_user"
  },
  "SwaggerAAD": {
    "AuthorizationUrl": "https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize",
    "TokenUrl": "https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token",
    "Scope": "api://<API-appregistration-client-id/access_as_user",
    "ClientId": "<client-id>"
  }
}

下面是 Swagger UI 身份验证的代码。

builder.Services.AddSwaggerGen(
    o => {
        o.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "Swagger Azure Ad", Version = "v1" });
        o.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
        {
            Name = "oauth2.0",
            Type = SecuritySchemeType.OAuth2,
            Flows = new OpenApiOAuthFlows
            {
                AuthorizationCode = new OpenApiOAuthFlow
                {
                    AuthorizationUrl = new Uri(builder.Configuration["SwaggerAAD:AuthorizationUrl"]),
                    TokenUrl = new Uri(builder.Configuration["SwaggerAAD:TokenUrl"]),
                    Scopes = new Dictionary<string, string>
                    {
                        {builder.Configuration["SwaggerAAD:Scope"],"Access API as User" }
                    }
                }
            }
        });
        o.AddSecurityRequirement(new OpenApiSecurityRequirement
        {
            {
                new OpenApiSecurityScheme
                {
                    Reference=new OpenApiReference{Type=ReferenceType.SecurityScheme,Id="oauth2"}
                },
                new []{builder.Configuration["SwaggerAAD:Scope"]}
            }
        });
    });
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(
        o =>
        {
            o.OAuthClientId(builder.Configuration["SwaggerAAD:ClientId"]);
            o.OAuthUsePkce();
            o.OAuthScopeSeparator(" ");
        });
}

我完整的program.cs

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Options;
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(
    o => {
        o.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "Swagger Azure Ad", Version = "v1" });
        o.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
        {
            Name = "oauth2.0",
            Type = SecuritySchemeType.OAuth2,
            Flows = new OpenApiOAuthFlows
            {
                AuthorizationCode = new OpenApiOAuthFlow
                {
                    AuthorizationUrl = new Uri(builder.Configuration["SwaggerAAD:AuthorizationUrl"]),
                    TokenUrl = new Uri(builder.Configuration["SwaggerAAD:TokenUrl"]),
                    Scopes = new Dictionary<string, string>
                    {
                        {builder.Configuration["SwaggerAAD:Scope"],"Access API as User" }
                    }
                }
            }
        });
        o.AddSecurityRequirement(new OpenApiSecurityRequirement
        {
            {
                new OpenApiSecurityScheme
                {
                    Reference=new OpenApiReference{Type=ReferenceType.SecurityScheme,Id="oauth2"}
                },
                new []{builder.Configuration["SwaggerAAD:Scope"]}
            }
        });
    });
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(
        o =>
        {
            o.OAuthClientId(builder.Configuration["SwaggerAAD:ClientId"]);
            o.OAuthUsePkce();
            o.OAuthScopeSeparator(" ");
        });
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
  • Azure AD API 应用程序注册的重定向 URL 在 Web 应用程序中设置,如下所示。

enter image description here

  • 对于 SwaggerAAD 应用程序注册,我将重定向 URL 设置为单页应用程序,如下所示。

enter image description here

  • 确保您的 API 获得管理员同意。

enter image description here

这里授权成功,没有任何错误。

enter image description here

enter image description here

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.