如何配置 OpenIddict 以在众所周知的端点上使用 CORS 中间件?

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

我正在设置一个测试项目来总体了解 OpenID Connect 和具体了解 OpenIddict。我在 ASP.NET Core 8 中设置了 3 个项目,一个 ResourceAPI、一个 AuthServer 和一个客户端 (Blazor)。它们都在本地运行,但在不同的端口上。

我想设置授权代码流程。我根据Balosar 示例在服务器和客户端中进行了适当的配置。 当运行客户端时,发生的第一件事是调用

.well-known/openid-configuration
端点,正如我所料。我收到响应,但由于缺少 CORS 标头,它被我的浏览器 (Brave) 阻止:

从源“https://localhost:7098”访问“https://localhost:7120/.well-known/openid-configuration”处的 XMLHttpRequest 已被 CORS 策略阻止:无“Access-Control-Allow-Origin” ' 标头存在于所请求的资源上。 确实没有 CORS 标头,并且该错误对我来说是有意义的,因为应用程序位于不同的端口上。

我在AuthServer中添加了CORS配置。 深入研究中间件的 OpenIddict 处理,我注意到除非我在配置中启用端点通过,否则不会运行其他中间件,包括 CORS 中间件。

因为没有配置可以让我在

.well-known/openid-configuration
端点上启用直通(即使实现了,我也不希望自己实现它)并且不知道如何继续。

我在 Chavlet 先生(OpenIddict 作者)关于类似问题的问题上找到了这个答案,这让我觉得我做错了什么,但我不知道是什么

您必须使用 CORS 作为授权端点的事实让我认为您做错了什么。

我是否缺少一些允许 OpenIddict 使用 CORS 的配置细节,或者我是否误解了流程?

这是我的 AuthServer 配置。请注意,授权代码流程尚未完全实现,我想在继续之前克服这个 CORS 障碍。 另请注意,我正在降级模式下运行,因为这就是我在真实代码库中设置后将使用的模式。

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddCors(opt => opt.AddPolicy("AllowThePlaygroundClient", policy => policy
        .WithOrigins("https://localhost:7098")
        .AllowAnyHeader()
        .AllowAnyMethod()
        .AllowCredentials())
    )
    .AddOpenIddict()
    .AddServer(opt =>
    {
        opt.EnableDegradedMode();
        opt.AddEphemeralEncryptionKey();
        opt.AddEphemeralSigningKey();
        opt.DisableAccessTokenEncryption();

        opt.AllowPasswordFlow();
        opt.AllowAuthorizationCodeFlow();
        opt.SetTokenEndpointUris("connect/token");

        opt.AddEventHandler<ValidateTokenRequestContext>(builder => builder.UseInlineHandler(context =>
        {
            // TODO: Add validation logic
            return default;
        }));
        opt.UseAspNetCore()
            .EnableTokenEndpointPassthrough();
    });

var app = builder.Build();

app.UseCors("AllowThePlaygroundClient");

app.MapPost("connect/token", (Delegate)((HttpContext context) =>
{
    var request = context.GetOpenIddictServerRequest() ?? throw new InvalidOperationException("Not a valid OIDC request");

    if (request.IsPasswordGrantType())
    {
        // In a reald world scenario we should never tell why the authentication has failed
        if (request.Username != _user.email || request.Password != _user.password)
        {
            return Task.FromResult(Results.NotFound("Invalid credentials!"));
        }

        var identity = new ClaimsIdentity(authenticationType: "jivete")
            .SetClaim(Claims.Subject, _user.email)
            .SetClaim(Claims.Name, _user.name)
            .SetClaim(Claims.Email, _user.email);

        identity.SetAudiences(new[] { "resourceApi" });
        return Task.FromResult(Results.SignIn(new ClaimsPrincipal(identity), authenticationScheme: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme));
    }

    throw new InvalidOperationException("The specified grant type is not supported.");
}));

app.Run();

这是客户端的配置:

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddOidcAuthentication(opt =>
{
    opt.ProviderOptions.Authority = "https://localhost:7120";
    opt.ProviderOptions.ClientId = "myClientId";
    opt.ProviderOptions.ResponseType = "code";
    opt.ProviderOptions.ResponseMode = "query";

    opt.ProviderOptions.DefaultScopes.Add("roles");
    opt.UserOptions.RoleClaim = "role";
});

await builder.Build().RunAsync();
asp.net-core cors blazor openid-connect openiddict
1个回答
0
投票

要使此场景发挥作用,必须在身份验证中间件(负责调用 OpenIddict,以

IAuthenticationRequestHandler
的形式实现)启动之前调用 CORS 中间件。

当使用最小 Web 主机(即

WebApplication.CreateBuilder(args)
)时,身份验证中间件会在 ASP.NET 团队选择的位置为您注册,这不一定有效,具体取决于场景。

为了防止这种情况,请手动注册身份验证和授权中间件:

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();
app.UseCors("AllowThePlaygroundClient");
© www.soinside.com 2019 - 2024. All rights reserved.