在 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/