2

我有一个 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 应用程序,我不会遇到这个问题。

可能是什么问题?

这是我的入口 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();
}
4

2 回答 2

0

在 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);
    }
});
于 2018-11-13T12:16:37.873 回答
0

我知道这很旧,但我在 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 页面,并且在重新部署后它会突然工作。所以我也添加app.UseHttpsRedirection();了该Configure方法,它似乎每次都有效。

编辑:在此博客中稍稍说明了为什么需要将 ForwardLimit 至少设置为 2。

于 2020-08-19T14:31:45.587 回答