我大致关注了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端点),并且我不控制服务器激活允许的来源。
我使用 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 应用程序中,如下所示。
对于 SwaggerAAD 应用程序注册,我将 RedirectUrl 放置在单页应用程序中,如下所示。
我从 Swagger 客户端应用程序注册中获取了端点值。
我在下面添加了以下API权限。
当我将authorizationUrl和tokenUrl放入Program.cs时,我收到以下错误。因此,我将这些值放入 appsettings.json 文件中。
将authorizationUrl和tokenUrl放入appsettings.json文件后,我收到了下面的输出,没有任何错误。
输出: