【问题标题】:ASP.NET Core 2.0, Kubernetes, https missing in reply address?回复地址中缺少 ASP.NET Core 2.0、Kubernetes、https?
【发布时间】:2020-08-20 21:00:59
【问题描述】:

我有一个 ASP.NET Core 2.0 Web 应用程序部署到 Kubernetes 集群。该应用程序使用 Azure AD 对某些受保护页面进行身份验证。 Kubernetes 集群使用 Nginx 入口控制器设置,让我们加密以支持 https。

我可以毫无问题地访问https://x.eastus.cloudapp.azure.com,并且通过单击网站上的链接,我会被定向到https://x.eastus.cloudapp.azure.com/link,也没有问题。

但是,当我点击需要登录用户的链接时,我得到:

Sign in
Sorry, but we’re having trouble signing you in.

AADSTS50011: The reply address 'http://x.eastus.cloudapp.azure.com/signin-oidc' does not match the reply addresses configured for the application: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx'. More details: not specified

请注意,上面的 URL 缺少 https,这就是问题所在。

我已将“https://x.eastus.cloudapp.azure.com/signin-oidc”注册为 Azure AD 中应用程序的回复 URL。

但是,我不明白为什么登录时使用的回复网址缺少https。

如果我将完全相同的应用程序部署到 Azure Web 应用程序,我不会遇到这个问题。

可能是什么问题?

这是我的 Ingress YAML 文件:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: x-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    # Add to generate certificates for this ingress
    kubernetes.io/tls-acme: 'true'
spec:
  rules:
    - host: x.eastus.cloudapp.azure.com
      http:
        paths:
          - path: /
            backend:
              serviceName: x-service
              servicePort: 80
  tls:
    # With this configuration kube-lego will generate a secret called `x-tls-secret`
    # for the URL `x.eastus.cloudapp.azure.com`
    - hosts:
        - "x.eastus.cloudapp.azure.com"
      secretName: x-tls-secret

我在 Startup.cs 中有以下代码:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders =
            ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    });

    services.Configure<MvcOptions>(options =>
    {
        options.Filters.Add(new RequireHttpsAttribute());
    });

    services.AddAuthentication(sharedOptions =>
    {
        sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
    .AddAzureAd(options => Configuration.Bind("AzureAd", options))
    .AddCookie();

    services.AddMvc();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseForwardedHeaders();

    app.UseStaticFiles();

    app.UseAuthentication();
}

【问题讨论】:

标签: nginx asp.net-core kubernetes azure-active-directory kubernetes-ingress


【解决方案1】:

在 Configure 方法中添加自定义中间件以执行手动 http-https 重定向

app.Use(async (context, next) =>
{
    if (context.Request.IsHttps || context.Request.Headers["X-Forwarded-Proto"] == Uri.UriSchemeHttps)
    {
        await next();
    }
    else
    {
        string queryString = context.Request.QueryString.HasValue ? context.Request.QueryString.Value : string.Empty;
        var https = "https://" + context.Request.Host + context.Request.Path + queryString;
        context.Response.Redirect(https);
    }
});

【讨论】:

    【解决方案2】:

    我知道这很旧,但我在 ASP .NET Core 3 和带有自定义 OpenID Connect 提供程序的 IdentityModel 库中遇到了类似的问题。重定向网址也将是 http 而不是 https。

    我必须做很多事情才能最终让它发挥作用:

    • 配置转发标头以告诉 ASP .NET Core 使用入口发送的 x-forwared-for 和 x-forwarded-proto 标头
    • 告诉 ASP .NET Core 信任来自 Kubernetes 网络的代理
    • 提高告诉 ASP .NET Core 可以发生多少转发的转发限制

    这里是相关的启动代码(一定要根据你的集群修改IP范围:

      public void ConfigureServices(IServiceCollection services)
      {
        services.Configure<ForwardedHeadersOptions>(options =>
        {
          // This tells the middleware to update IP and scheme according to forwarded headers
          options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
          options.ForwardLimit = 2;
    
          // Add Kubernetes Networks to trusted networks
          options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("10.42.0.0"), 16));
          options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("the IP range of our cluster nodes"), 27));
        });
    
        // ...
      }
    
      public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
      {
        if (env.IsDevelopment())
        {
          app.UseDeveloperExceptionPage();
        }
        else
        {
          app.UseExceptionHandler("/Error");
    
          // Enable to process forward headers from https proxy like ingress nginx, this middleware must run before others
          // configuration is above in ConfigureServices
          app.UseForwardedHeaders();
        }
    
        // ...
      }
    

    奇怪的是,这只有时会起作用。有时它仍然会尝试重定向到 HTTP 页面,并且在重新部署后它会突然工作。所以我还在Configure 方法中添加了app.UseHttpsRedirection();,它似乎每次都能正常工作。

    编辑:在this blog 中有所下降,它解释了为什么需要将 ForwardLimit 至少设置为 2。

    【讨论】:

      猜你喜欢
      • 2018-01-24
      • 2018-01-24
      • 2015-06-05
      • 1970-01-01
      • 1970-01-01
      • 2018-03-02
      • 2019-10-10
      • 1970-01-01
      相关资源
      最近更新 更多