ASP.NET Core中UseHttpsRedirection和AddDirectToHttpsPermanent之间的区别

Wel*_*ing 3 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()
    );
}
Run Code Online (Sandbox Code Playgroud)

据我所知,我必须使用重写器来设置AddRedirectToWwwPermanent.我的问题是,我应该同时使用app.UseHttpsRedirection()AddRedirectToHttpsPermanent()吗?或者,如果他们做同样的事情,我应该删除哪些?

我只是想确保我正确地重定向到Https,与Wwww重定向一起使用.

pok*_*oke 8

AddRedirectToHttpsPermanent(或其兄弟姐妹AddRedirectToHttps)RedirectToHttpsRule在重写者身上添加了一个.此规则的工作方式如下:

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();
}
Run Code Online (Sandbox Code Playgroud)

因此,这基本上获取当前主机名,并构建一个看起来相同的新URL,除非它具有https://前面的.然后它设置301 HTTP状态代码并通过Location标头返回新的URL .

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

相比之下,这就是内部工作的方式:HttpsRedirectionMiddleware

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;
Run Code Online (Sandbox Code Playgroud)

因此,这将从传入的请求中获取主机名,然后使用UriHelper与当前请求完全相同的构建绝对URL ,除了它使用该https://方案.然后它设置307 HTTP状态代码结果并通过Location标头返回新的URL .由于它不会调用以后的中间件,因此也会结束响应.

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

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


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

我个人坚持,HttpsRedirectionMiddleware因为它非常清楚地传达了它的目的.但是如果你有一个RewriteMiddleware到位的话,我只需要替换HttpsRedirectionMiddleware一个RedirectToHttpsRule用于重写的中间件,所以你只需要一个执行重定向的中间件. - 但最终,这无关紧要.

  • 不,两个中间件都会在最后终止请求,而不会调用管道中的下一个中间件。因此,首先注册的任何中间件都将被执行,然后结束响应。所以不会有任何效果的组合。 (2认同)