You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

指定其他Scheme发起Challenge时自定义AuthenticationHandler仍被调用如何处理

问题原因

你遇到的问题根因是自定义认证方案被纳入了全局默认的认证/挑战流程,当你触发任意认证相关逻辑时,所有未被排除在默认策略外的Handler都会被执行。即便你显式指定了本次Challenge使用OIDC方案,只要自定义Handler的HandleAuthenticateAsync返回NoResult,认证中间件就会尝试触发所有已注册方案的挑战逻辑,最终自定义的跳转覆盖了OIDC的跳转。

解决方案

下面给出两种可直接落地的修改方式:

方案1:明确指定全局默认的认证/挑战方案,排除自定义方案

修改启动时的服务注册代码,显式声明所有默认认证相关的方案都使用OIDC的方案,自定义方案仅作为按需调用的独立方案存在:

var authBuilder = 
    services.AddAuthentication(options =>
    {
        options.DefaultScheme = OpenIdConnectDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        options.DefaultSignInScheme = OpenIdConnectDefaults.AuthenticationScheme;
        options.DefaultSignOutScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
            .AddScheme<MyCustomHandlerOptions, MyCustomHandler>("MyCustomScheme", null)
            .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
            .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
            .AddInMemoryTokenCaches();

这个修改后,全局默认的挑战逻辑只会触发OIDC方案的挑战,自定义方案只有在[Authorize]特性、或者Challenge方法显式指定MyCustomScheme时才会被执行。

方案2:修改自定义Handler的逻辑,仅当显式指定自身方案时才执行跳转

如果不想修改全局注册逻辑,可以直接修改自定义Handler的逻辑,仅在明确调用自身方案时才执行对应操作:

protected override Task HandleChallengeAsync(AuthenticationProperties properties)
{
    // 仅当本次Challenge显式指定了MyCustomScheme时才执行自定义跳转
    var isTargetScheme = Context.GetEndpoint()?.Metadata.GetMetadata<IAuthorizeData>()?.AuthenticationSchemes?.Contains("MyCustomScheme") == true
        || (properties.Items.TryGetValue(".AuthScheme", out var targetScheme) && targetScheme?.ToString() == "MyCustomScheme");
    if (isTargetScheme)
    {
        Context.Response.Redirect("/MyLoginPage");
    }
    return Task.CompletedTask;
}

protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
    // 仅当显式指定自身方案时才执行认证逻辑,否则直接返回NoResult
    var authorizeData = Context.GetEndpoint()?.Metadata.GetMetadata<IAuthorizeData>();
    if (authorizeData?.AuthenticationSchemes?.Contains("MyCustomScheme") != true)
    {
        return Task.FromResult(AuthenticateResult.NoResult());
    }
    // 此处保留你原本的自定义认证逻辑
    return Task.FromResult(AuthenticateResult.NoResult());
}
验证

修改完成后再访问Account/SignInOidc接口,自定义Handler不会再执行跳转逻辑,会正常跳转到OIDC身份提供方的登录页,同时显式标记[Authorize(AuthenticationSchemes = "MyCustomScheme")]的接口逻辑不受影响。

内容的提问来源于stack exchange,提问作者Dave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 14:18:05