c# - ASP.NET Core 中 UseHttpsRedirection 和 AddDirectToHttpsPermanent 的区别

标签 c# asp.net-core

Startup.cs 文件中,考虑以下内容:

public void ConfigureServices(IServiceCollection services)
{
    // Irrelevant code removed

    services.AddHttpsRedirection(options =>
    {
        options.RedirectStatusCode = StatusCodes.Status301MovedPermanently;
    });
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // Irrelevant code removed

    app.UseHttpsRedirection();

    app.UseRewriter(new RewriteOptions()
        .AddRedirectToWwwPermanent()
        .AddRedirectToHttpsPermanent()
    );
}

据我所知,我必须使用 Rewriter 来设置 AddRedirectToWwwPermanent。我的问题是,我应该同时使用 app.UseHttpsRedirection()AddRedirectToHttpsPermanent() 吗?或者如果他们做完全相同的事情,我应该删除哪个?

我只想确保与 Wwww 重定向一起正确重定向到 Https。

最佳答案

AddRedirectToHttpsPermanent (或其兄弟 AddRedirectToHttps )添加一个 RedirectToHttpsRule给重写者。这条规则works like this :

if (!context.HttpContext.Request.IsHttps)
{
    var host = context.HttpContext.Request.Host;
    if (SSLPort.HasValue && SSLPort.Value > 0)
    {
        // a specific SSL port is specified
        host = new HostString(host.Host, SSLPort.Value);
    }
    else
    {
        // clear the port
        host = new HostString(host.Host);
    }

    var req = context.HttpContext.Request;
    var newUrl = new StringBuilder().Append("https://").Append(host).Append(req.PathBase).Append(req.Path).Append(req.QueryString);
    var response = context.HttpContext.Response;
    response.StatusCode = StatusCode;
    response.Headers[HeaderNames.Location] = newUrl.ToString();
    context.Result = RuleResult.EndResponse;
    context.Logger?.RedirectedToHttps();
}

所以这基本上是获取当前主机名,并构建一个看起来相同的新 URL,只是它前面有一个 https://。然后它设置 301 HTTP 状态代码并通过 Location header 返回新的 URL。

然后规则作为 RewriteMiddleware 的一部分执行这基本上只是循环遍历所有已注册的规则,并最终运行上面的代码,然后结束响应。

相比之下,HttpsRedirectionMiddleware 是这样的works internally :

if (context.Request.IsHttps || !TryGetHttpsPort(out var port))
{
    return _next(context);
}

var host = context.Request.Host;
if (port != 443)
{
    host = new HostString(host.Host, port);
}
else
{
    host = new HostString(host.Host);
}

var request = context.Request;
var redirectUrl = UriHelper.BuildAbsolute(
    "https",
    host,
    request.PathBase,
    request.Path,
    request.QueryString);

context.Response.StatusCode = _statusCode;
context.Response.Headers[HeaderNames.Location] = redirectUrl;

_logger.RedirectingToHttps(redirectUrl);

return Task.CompletedTask;

所以这将从传入的请求中获取主机名,然后使用 UriHelper 构建一个绝对 URL,它看起来与当前请求完全一样,除了它使用 https:// 方案。然后它设置 307 HTTP 状态代码结果并通过 Location header 返回新的 URL。由于它不调用后面的中间件,这也将结束响应。

是的,这两个解决方案非常不同(不是):它们使用几乎相同的代码并产生相同的结果。唯一实际的区别是 HttpsRedirectionMiddleware 使用 HTTP 307 status code默认情况下。

如果您更喜欢一个状态码而不是另一个,您完全可以配置两个中间件来使用您喜欢的状态码。


那么您应该使用哪个中间件来启用 HTTPS 重定向?这并不重要。默认情况下,ASP.NET Core 模板附带 HttpsRedirectionMiddleware,但该中间件也只存在于 ASP.NET Core 2.1 之后。

我个人会坚持使用 HttpsRedirectionMiddleware,因为它非常清楚地传达了它的目的。但是如果你有一个 RewriteMiddleware 无论如何,我只是将 HttpsRedirectionMiddleware 替换为 RedirectToHttpsRule 用于重写中间件,所以你只有一个执行重定向的单个中间件。 – 但最终,这真的没关系。

关于c# - ASP.NET Core 中 UseHttpsRedirection 和 AddDirectToHttpsPermanent 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52432456/

相关文章:

c# - ASP.NET Core 3.0 WebAPI - 在 Controller 方法中处理异常时,为什么我仍然收到 InternalServerError?

c# - .NET Core 2.0 带路由的最小 WebHost

c# - 让 WCF 回调与 netTcpBinding 一起工作

c# - XmlEnumAttribute 在 WCF 请求中不起作用

c# - MEF配置

c# - 为什么 .Net Core/Azure Web 作业示例不起作用?

.net - swagger .net core API 操作错误的不明确 HTTP 方法

c# - 无法在 WPF 应用程序中创建自定义命令

c# - 如何使用 c# 在 Windows 10 中的任务栏上创建工具栏工具

azure - 将 Asp.net core mvc 应用程序从 Visual Studio 重新发布到 azure 应用程序服务是否会生成指向实时网站的新链接或与之前的链接相同?