使用从Azure API管理转发的网站处理AAD登录

问题描述

我有一个Service Fabric群集,该群集正在运行无法公开给Internet的服务(无状态ASP.Net Core)。对服务的请求通过API管理进行路由。

Incoming request ==> https://blah.trafficmanager.net/routeName
forwarded ==> https://10.0.4.6:[port]/routeName

这无需任何身份验证即可正常工作。我正在连接AAD身份验证,因为我们需要将其锁定到客户端注册(由于具有时间限制的海拔请求)。我已经将服务设置为使用AAD身份验证,并且在我的本地开发Service Fabric集群中运行时,可以使用以下参数正常工作(即,提示登录,根据角色对路由进行选通):

"AzureAd:ClientId": "[client id]","AzureAd:Domain": "[tenant].onmicrosoft.com","AzureAd:Instance": "https://login.microsoftonline.com/","AzureAd:SignedOutCallbackPath": "/signout-callback-oidc","AzureAd:CallbackPath": "/signin-oidc","AzureAd:TenantId": "[tenant id]",

当我部署它并尝试通过https://blah.trafficmanager.net/routeName重定向https://10.0.4.6:44321/signin-oidc进行访问时,最终得到:

enter image description here

这是我的startup.cs代码

/// <summary>
/// Configure services
/// </summary>
/// <param name="services">Service collection</param>
public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpContextAccessor();

    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.Unspecified;

        // Handling SameSite cookie according to https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1
        options.HandleSameSiteCookieCompatibility();
    });

    // Sign-in users with the Microsoft identity platform
    services.AddMicrosoftWebAppAuthentication(this.Configuration);
    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders = ForwardedHeaders.All;

        options.KNownProxies.Add(IPAddress.Parse("10.0.4.6"));
    });

    // services.AddControllers();
    services.AddControllers(options =>
    {
        var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();
        options.Filters.Add(new Authorizefilter(policy));
    });
}

/// <summary>
/// Configure app
/// </summary>
/// <param name="app">App builder</param>
/// <param name="env">Environment</param>
public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
    app.UseDeveloperExceptionPage();

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();

    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();

    app.UseForwardedHeaders();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

我想知道是否可以做些什么才能使群集节点上的此服务能够对通过APIM传入的请求进行身份验证。

谢谢!

解决方法

我可以使用以下方法覆盖回复网址:

        services.Configure<OpenIdConnectOptions>(
            OpenIdConnectDefaults.AuthenticationScheme,options =>
            {
                var redirectToIdpHandler = options.Events.OnRedirectToIdentityProvider;
                options.Events.OnRedirectToIdentityProvider = async context =>
                {
                    // Call what Microsoft.Identity.Web is doing
                    await redirectToIdpHandler(context);

                    // Override the redirect URI so that auth works behind APIM
                    context.ProtocolMessage.RedirectUri = this.Configuration["AzureAd:RedirectUri"];
                };
            });

然后我遇到了身份验证问题,因为它会循环很多次并最终给出错误标志。我发现这是因为我的回复网址是主站点,而不是signin-oidc。当我添加带有APIM的signin-oidc作为回复URL时,APIM失败,因为没有使用该名称的路由。我创建了一个新API,将signin-oidc转发到后端的同一路由。

现在,从AAD回来的回复在signin-oidc上命中了我的APIM,并转发到了背面。这样就可以完成身份验证。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...