应用程序在运行HTTPS时发送的重定向URI为HTTP而不是HTTPS

24

我有一个 Asp .net core MVC 应用程序。它连接到 Identity Server 4 进行身份验证。托管在 Docker Swarm 上。

MVC 应用程序托管在 https://XXXXXXX 上。

ConfigurServies

services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        })
             .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
            {
                //options.DataProtectionProvider = DataProtectionProvider.Create(new DirectoryInfo(@"C:\temp-keys\"));
                // when the identity has been created from the data we receive,
                // persist it with this authentication scheme, hence in a cookie
                options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                // Identity server endpoint
                options.Authority = settingsSetup.IdentityServerEndpoint;

                // Client id to login with
                options.ClientId = settingsSetup.ClientId;
                // Client secret.
                options.ClientSecret = settingsSetup.Secret;

                // Scope of our API
                options.Scope.Add("testapi");
                options.Scope.Add("devconsole");
                // adding offline_access to get a refresh token
                options.Scope.Add("offline_access");

                options.ResponseType = "code id_token";
                options.SaveTokens = true;
                options.GetClaimsFromUserInfoEndpoint = true;
            });
当我尝试运行应用程序时,出现了重定向URI不匹配的错误。
Invalid redirect_uri: http://developerconsole.XXXXX.io/signin-oidc
{
  "ClientId": "BB1D2DA8-D7E4-4AF5-94FA-19EAD6B7D711.apps.XXXXX.biz",
  "ClientName": "Developer Console",
  "AllowedRedirectUris": [
    "http://localhost:55000/signin-oidc",
    "http://localhost:55000/auth.html",
    "http://localhost:55000/auth-silent.html"
    "https://developerconsole.XXXXX.io/signin-oidc"
  ],
  "SubjectId": "21379983",
  "RequestedScopes": "",
  "Raw": {
    "client_id": "BB1D2DA8-D7E4-4AF5-94FA-19EAD6B7D711.apps.XXXXX.biz",
    "redirect_uri": "http://developerconsole.XXXXX.io/signin-oidc",
    "response_type": "code id_token",
    "scope": "openid profile testapi devconsole offline_access",
    "response_mode": "form_post",
    "nonce": "636625889658410682.MjNlMmQwNjgtZmY0MC00MmVkLWFiNmMtN2M2YmQ5YTM5ZTQ3NjFiYzI2ZjktZWM0Yi00NDk3LTk1ZWMtNjJkYjViMDYwMTJm",
    "state": "CfDJ8Pwa8A3ipXlKtuyxNMpMxAz5QUFmdSunRKdlKS9sS390AKp8gIUZShQUMMCkFAhYLytitgsXUBgwlQDJaJvtHFqzHygLCPwS8Jab6IJzhpry90qS51E1y_eRlppamRDOzYDZ6fcDFzWV1U43BTP2B6pnPTSLNcZRaooyGBXtNokeUqOJ--u-_MOQB8Bw3n2cRyV4kisHNkslD1Gsi2wn1Cx6aTVlqzw_pxHelAXm1P8FyDJpD7G0azFgKgpQF0DRJtC5penRJQzHIHvQN8v4ECGeuSD1zlyfJYClLO2r6kY_R2OYqtBkV0r_SNc9h7xUYmnVaHKQzYqVc_mJO4iLLSMTZrBUICZWR8c4PZw0Os3N",
    "x-client-SKU": "ID_NET",
    "x-client-ver": "2.1.4.0"
  }
}
错误是由于我将"https://developerconsole.XXXXX.io/signin-oidc"作为重定向uri,而不是"http://developerconsole.XXXXX.io/signin-oidc"导致的。 我不想添加HTTP重定向URI。
为什么我的应用程序生成的重定向URI是http而不是https?
如果我确实添加了HTTP,我会收到一个非常烦人的Correlation错误。 我认为这是由于服务器返回https而不是http造成的,因为服务器自动将http转换为https。
未处理的异常发生在处理请求时。 例外:关联失败。 Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler + d__12.MoveNext()
堆栈查询cookie标头异常:关联失败。 Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler + d__12.MoveNext() System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task 任务) Microsoft.AspNetCore.Authentication.AuthenticationMiddleware + d__6.MoveNext() System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task 任务) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware + d__7.MoveNext()
我可能不需要提到这在本地主机上运行正常:/

2
这可能是因为您在(L7)负载均衡器后面,并且负载均衡器后面的内部通信是通过HTTP而不是HTTPS进行的吗? - spender
4
如果是这种情况,Microsoft.AspNetCore.HttpOverrides 中的转发标头中间件可能会有所帮助。请在此处查看:https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.0 - spender
如果是第4层负载均衡,则上述不适用。 - spender
你能再确认一下 settingsSetup.IdentityServerEndpoint 是否正确吗? - penleychan
如果不正确,身份验证服务器就不会向我返回正确的响应。服务器已经成功为我登录,问题出在我的应用程序没有正确地使登录失效。 - Linda Lawton - DaImTo
显示剩余3条评论
6个回答

50

解决方案非常简单。通过设置UseForwardedHeaders,现在将所有请求发送为HTTPS。

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

相关性失败了。

现在已经修复,我不再需要http和https重定向URI了。


15
如果应用程序部署在Linux上(例如,在linux docker容器中的.NET core应用程序),除了设置正向头之外,还需要清除KnownNetworksKnownProxies,以确保重定向URL保持为https。请参见https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.2#forward-the-scheme-for-linux-and-non-iis-reverse-proxies 获取更多详细信息。 - Suketu Bhuta
3
@SuketuBhuta 那个信息真的很有用。 - avg_bloke
1
我们不得不使用这个解决方案,因为我们在aws ELB后面的NGINX conf中将HTTP重定向到HTTPS,对我们来说它非常有效。 - Vibhanshu Biswas
@SuketuBhuta 你是如何/在哪里/何时清除了 KnownNetworksKnownProxies 的? - David
@David,看一下我上面链接的文章中的这个部分:https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.2#forward-the-scheme-for-linux-and-non-iis-reverse-proxies-1,基本上在设置了`ForwardingHeader`之后就可以清除了。希望这能帮到你。 - Suketu Bhuta
我不得不添加 .addForwardedheaders 和 .useforwardedheaders()。请查看我的答案:https://dev59.com/FaTja4cB1Zd3GeqPIuK5#68757575 - Enrico

3

ASP.NET Core 6 新增了一种更简单的方法,用于在 TLS 在到达部署的 Web 应用程序之前终止的非 IIS 方案中实现此目的:

要在非 IIS 场景下从代理转发方案,请通过将环境变量 ASPNETCORE_FORWARDEDHEADERS_ENABLED 设置为 true 来启用转发标头中间件。

设置此变量可解决我的 Docker 应用程序在 Azure 容器应用程序中运行时出现的问题,而无需对 Program.cs 进行任何更改。


这个解决方法在一个运行在AWS ECS环境中的.NET 6.0 Docker容器里对我奏效了。 - Eternal21

2

Ubuntu 18、Nginx 和 .NetCore 3.1 协同工作的方式如下:

app.UseForwardedHeaders(new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.All
            });
 

/etc/nginx/nginx.conf

fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;

/etc/nginx/sites-enabled/default 或者你的Web配置文件

location / {

# under your configuration
    proxy_set_header X-Forwarded-Proto $scheme;
}


然后它开始重定向到https,没有nginx配置,我收到了503错误。

你测试过 .NET 6 吗? - Linda Lawton - DaImTo
1
我还没有更新项目。等我更新了,我也会编辑这个回复。 - Kamil

1

请注意这个非常重要的细节:场景是“无法添加转发头并且所有请求都是安全的”。我在一个k8s集群中托管了一个IdentityServer4服务,该服务接收来自外部的安全请求和来自集群内部的非安全请求,而这个黑客中间件导致我的发现文档始终包含HTTPS URL,这对于内部请求是个问题。如果您计划在Kubernetes集群中托管IdentityServer4,请不要使用此方法 - 其他应用程序可能会遇到相同的问题。 - Simone

0
@Kamil是解决我的问题的关键。 基本上是相同的配置(Ubuntu 16.04,Net Core 3.1和nGinx)。这个设置是为了使Google身份验证在我的在线网站上也能正常工作(在本地一切都正常工作),避免了redirect_uri_mismatch问题。
在Startup.cs的ConfigureServices方法中,我有以下代码:
services.Configure<ForwardedHeadersOptions>(options => {});

在Startup.cs文件中的Configure方法中:
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    RequireHeaderSymmetry = false,
    ForwardedHeaders = ForwardedHeaders.All,
});

app.UseForwardedHeaders();
app.UseHttpsRedirection();

在服务器上,文件/etc/nginx/sites-enabled/default中:
server {
     ...
     ssl on;
     ...
     location / {
          proxy_pass http://dotnet;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP       $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
     }
     ...
}

在文件/etc/nginx/nginx.conf中。
http {
    ...
    # Solution to get always HTTPS
    fastcgi_buffers 16 16k;
    fastcgi_buffer_size 32k;
    ...
}

-2

只需将此代码添加到您的web.config文件中,并将.com更改为您的网站,任何人在浏览器中输入URL都会直接重定向从HTTP到HTTPS的重定向URI。

<system.webServer>
    <rewrite>
      <rules>
        <rule name="IP Hit" stopProcessing="true">
          <match url="(.*)" />
          <conditions>
            <add input="{HTTP_HOST}" pattern="http://www.exemple.com" />
            <add input="{HTTPS}" pattern="off" ignoreCase="true" />
          </conditions>
          <action type="Redirect" url="https://www.exemple.com/{R:1}" redirectType="Permanent" />
        </rule>
      </rules>
    </rewrite>
    <urlCompression doDynamicCompression="true" doStaticCompression="true" dynamicCompressionBeforeCache="true" />
    <staticContent>
      <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="365:00:00" />
    </staticContent>
 <system.webServer>

这个答案只是将目标从http移动到https,它并不会使链接在https中呈现。 - Adam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接