我有一个 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();
我的应用程序注册身份验证设置如下:
并手动设置以下范围:
当我尝试在 Swagger UI 中进行身份验证时出现问题:
出现以下错误:
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 应用程序配置一起使用?.
我为 ASP .NET Core API 创建了一个示例 Swagger UI 授权,并且已成功授权,没有任何错误。
它似乎总是希望将重定向网址配置为单页应用程序?
是的,你是对的。唯一的方法是在
Single Page Application
平台中配置重定向URI。如果你使用Web平台,也会抛出同样的错误。
为了避免该错误,我将授权 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();
这里授权成功,没有任何错误。