Swagger 授权时产生“Auth ErrorTypeError: Failed to fetch”

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

我大致关注了Scott的博客并结合了Joseph的博客。不幸的是,我收到错误 Auth ErrorTypeError: 无法获取

授权配置如下(

{tenantId}
是有效的GUID)。

services.AddSwaggerGen(options =>
{
  options.AddSecurityRequirement(new() { ... });
  options.AddSecurityDefinition("oauth2", new()
  {
    Type = SecuritySchemeType.OAuth2,
    Flows = new()
    {
      AuthorizationCode = new()
      {
        AuthorizationUrl = new("https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize"),
        TokenUrl = new("https://login.microsoftonline.com/{tenantId}/common/v2.0/token"),
        Scopes = new Dictionary<string, string>
        {
          { "https://graph.microsoft.com/.default", "https://graph.microsoft.com/.default" }            
        }
      }
    }
  });
});

然后,我也有 UI 的配置,如下所示({clientId} 是有效的 GUID)。

app.UseSwaggerUI(options =>
{
  options.OAuthAppName("Beep");
  options.OAuthClientId("{clientId}");
  options.OAuthClientSecret("HakunaMatata");
  options.OAuthScopes(["https://graph.microsoft.com/.default" ]);
  options.OAuthUsePkce();
});

Swagger中的授权按钮会打开弹窗,请求调用时返回上述错误。我不明白问题发生在哪里,也不知道如何进一步排除故障。我唯一注意到的是,不提供任何范围会导致 Azure 中出现错误消息。提供范围甚至不会显示登录页面。我已经验证 .well-known 为授权和令牌端点生成正确的值。我验证了应用程序注册的秘密以及指向我的 Swagger 的重定向 URI (https://localhost:7001/swagger/oauth2-redirect.html) 的正确性。大多数相关问题都涉及隐式流程或 API 密钥,这不适用于我的情况。关于错误消息的类似问题是rathernotrewarding。我还尝试声明一个专用范围(api://d53180a4-0a79-4f7a-96aa-3f2eed32f559/SwaggerScope)并使用它向我显示登录页面,但选择用户会产生相同的错误消息。

我检查了网络调用,发现了一些意想不到的事情。显然,CORS 在令牌端点上触发并且它还报告 404 Not Found(这是自相矛盾的,但我认为未找到是由 CORS 引起的)。 URL 不是我在上面的配置中指定的(根据.well-known端点),并且我不控制服务器激活允许的来源。

我可以研究或尝试什么?

c# azure oauth-2.0 swagger authorization
1个回答
0
投票

我使用 Swagger UI Authorization for ASP.NET Core API 创建了这个项目,并且已成功授权,没有任何错误。

下面是我用于 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 类。

程序.cs

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Options;
using Microsoft.Identity.Web;
using Microsoft.OpenApi.Models;

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();

我将 ClientId、TenantId、AuthorizationUrl 和 TokenUrl 等值放置在 appsettings.json 中,而不是将它们放置在 program.cs 中。

appSettings.json

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "<YourDomain>.onmicrosoft.com",
    "TenantId": "<YourTenantID>",
    "ClientId": "<ClientId>",
    "CallbackPath": "/signin-oidc",
    "Scopes": "access_as_user"
  },
  "SwaggerAAD": {
    "AuthorizationUrl": "https://login.microsoftonline.com/<TenantId>/oauth2/v2.0/authorize",
    "TokenUrl": "https://login.microsoftonline.com/<TenantId>/oauth2/v2.0/token",
    "Scope": "https://graph.microsoft.com/.default",
    "ClientId": "<ClientId>"
  },

对于 Azure AD API 应用程序注册,重定向 URL 放置在 Web 应用程序中,如下所示。

enter image description here

对于 SwaggerAAD 应用程序注册,我将 RedirectUrl 放置在单页应用程序中,如下所示。

enter image description here

我从 Swagger 客户端应用程序注册中获取了端点值。

enter image description here

我在下面添加了以下API权限。

enter image description here

当我将authorizationUrl和tokenUrl放入Program.cs时,我收到以下错误。因此,我将这些值放入 appsettings.json 文件中。

enter image description here

将authorizationUrl和tokenUrl放入appsettings.json文件后,我收到了下面的输出,没有任何错误。

输出

enter image description here

enter image description here

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