在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()
);
}
据我所知,我必须使用重写器来设置
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
标头返回新的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
标头返回新的URL。由于它不会调用以后的中间件,因此也将结束响应。是的,这两个解决方案非常不同(不是):它们使用几乎相同的代码并产生相同的结果。唯一的实际区别是
HttpsRedirectionMiddleware
默认情况下使用HTTP 307 status code。如果您更喜欢一个状态码,则可以将两个中间件完全配置为使用您的首选状态码。
那么应该使用哪种中间件来启用HTTPS重定向?没关系。默认情况下,ASP.NET Core模板随
HttpsRedirectionMiddleware
一起提供,但是该中间件也仅在ASP.NET Core 2.1之后存在。我个人会坚持使用
HttpsRedirectionMiddleware
,因为它非常清楚地传达了其目的。但是,无论如何,如果您有一个RewriteMiddleware
,我将用一个HttpsRedirectionMiddleware
替换RedirectToHttpsRule
即可用于重写中间件,因此您只有一个执行重定向的中间件。 –但是最后,这并不重要。