asp.net core 中关联失败

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

我的 Web 应用程序无法使用 OpenIdConnect 进行身份验证。目前我在

OnRemoteFailure
上看到“关联失败”错误。

背景:

  • Service Fabric 无状态 .net core Web 应用程序
  • Azure B2C
  • 反向代理(Traefik)

启动:

    public void ConfigureServices(IServiceCollection services)
    {
        (...)

        services.AddMvc();

        (...)

        services.AddAuthorization();
        services.AddAuthentication(sharedOptions =>
        {
            sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        })
        .AddCookie()
        .AddOpenIdConnect(o =>
        {
            o.ClientId = clientId;
            o.Authority = $"https://login.microsoftonline.com/{tenantId}/{signinPolicy}/v2.0";
            o.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            o.SaveTokens = true;
            o.Events = new OpenIdConnectEvents
            {
                OnTokenValidated = async context =>
                {
                    (...)
                },
                OnRedirectToIdentityProvider = async context =>
                {
                    if (context.Request.Headers.TryGetValue("X-Forwarded-Prefix", out var prefix) && prefix.Count > 0 &&
                    context.Request.Headers.TryGetValue("X-Forwarded-Host", out var hostValues) && hostValues.Count > 0 &&
                    context.Request.Headers.TryGetValue("X-Forwarded-Proto", out var protoValues) && protoValues.Count > 0)
                    {
                        // Use external URL and path
                        string redirectUri = $"{protoValues.First()}://{hostValues.First()}{prefix.First()}{context.Options.CallbackPath}";
                        context.ProtocolMessage.RedirectUri = redirectUri;
                    }
                },
                OnTokenResponseReceived = async context =>
                {
                },
                OnAuthenticationFailed = async context =>
                {
                },
                OnRemoteFailure = async context =>
                {
                }
            };
            o.ConfigurationManager = new PolicyConfigurationManager($"https://login.microsoftonline.com/{tenantId}/{signinPolicy}/v2.0",
                                      new[] { signinPolicy });
        });

        (...)
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        app.UseStaticFiles();

        app.UseAuthentication();

        app.Use(async (context, next) =>
        {
            if (context.Request.Headers.TryGetValue("X-Forwarded-Prefix", out var prefix) && prefix.Count() > 0)
            {
                context.Request.PathBase = prefix.First();
            }
            await next.Invoke();
        });

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

控制器:

public class AccountController : Controller
{
    [HttpGet]
    public IActionResult SignIn()
    {
        if (Request.Headers.TryGetValue("X-Forwarded-Prefix", out var prefix) && prefix.Count() > 0)
        {
            return Challenge(new AuthenticationProperties { RedirectUri = prefix.First() }, OpenIdConnectDefaults.AuthenticationScheme);
        }
        else
        {
            (...)
        }
    }
    (...)
}

事件

OnTokenValidated
永远不会被触发。

关于反向代理,它基本上将 https://internal_url:port/internal_path 映射到 https://external_url/external_path

我检查了请求,这是访问的 GET:

https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize?p={signinPolicy}&client_id={clientId}&redirect_uri=https%3A%2F%2F{external_host}%2F{external_path}%2Fsignin-oidc&response_type=id_token&scope=openid%20profile&response_mode=form_post&nonce=(...)&x-client-SKU=ID_NET&x-client-ver=2.1.4.0

成功然后POST请求失败:

https://{external_url}/{external_path}/signin-oidc

此帖子包含表单数据

id_token
state

B2C 中配置的重定向 URL 为

https://{external_url}/{external_path}/signin-oidc
。我也尝试了
https://{external_url}/{external_path}
,但效果不佳。

我尝试使用转发标头,但没有帮助。

谁能指出我缺少的东西吗?

提前致谢!

asp.net-core azure-service-fabric openid-connect azure-ad-b2c traefik
2个回答
8
投票

我发现了问题。问题出在中间件的顺序上。身份验证中间件必须在 PathBase 上的更改之后发生。 在我的情况下不需要转发标头。

遵循固定的

Configure
方法。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.Use(async (context, next) =>
    {
        if (context.Request.Headers.TryGetValue("X-Forwarded-Prefix", out var prefix) && prefix.Count() > 0)
        {
            context.Request.PathBase = prefix.First();
        }
        await next.Invoke();
    });

    app.UseStaticFiles();

    app.UseAuthentication();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

0
投票

我发现使用它可以处理上下文中的所有属性。请求:

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.forwardedheadersextensions.useforwardedheaders?view=aspnetcore-8.0

更多信息:

https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-8.0

如果代理不在本地主机上,可能需要更多配置,请参阅:

https://stackoverflow.com/a/75987490

builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.KnownProxies.Add(IPAddress.Parse("127.0.10.1"));
});
© www.soinside.com 2019 - 2024. All rights reserved.