我们有一个多租户的asp.net core 2应用程序。
我们需要将对非安全网址的请求重定向到他们的https。我们必须通过代码而不是使用web.config或IIS来执行此操作,因为某些域具有https,而另一些域则没有。我们通过根据发出请求的主机检入数据库来检查哪个域需要此重定向。
是否可以在中间件中执行此操作?
谢谢。
答案 0 :(得分:0)
我找到了一种方法来做我们需要做的事情,并且在别人遇到相同问题的情况下也想与大家分享。
我们已经使用Microsoft.AspNetCore.Rewrite库通过URL重写规则解决了该问题。
在startup.cs中,我们添加以下代码
app.UseRewriter(new RewriteOptions().Add(new RedirectToSecureRule()));
然后我们添加类RedirectToSecureRule
public class RedirectToSecureRule : IRule
{
public virtual void ApplyRule(RewriteContext context)
{
var currentRequest = context.HttpContext.Request;
if (currentRequest.IsHttps)
{
context.Result = RuleResult.ContinueRules;
return;
}
if (currentRequest.Host.Host.Equals("localhost", StringComparison.OrdinalIgnoreCase))
{
context.Result = RuleResult.ContinueRules;
return;
}
if (context.HttpContext.Items["TenantSsl"] == null || !Convert.ToBoolean(context.HttpContext.Items["TenantSsl"]))
{
context.Result = RuleResult.ContinueRules;
return;
}
var httpsUrl = UriHelper.BuildAbsolute("https", new HostString(currentRequest.Host.Value), currentRequest.PathBase, currentRequest.Path, currentRequest.QueryString);
var response = context.HttpContext.Response;
response.StatusCode = 301;
response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Location] = httpsUrl;
context.Result = RuleResult.EndResponse;
}
}
如您所见,请求是否已经是https,我们什么都不做。对于localhost也是一样,尽管此条件不是必需的,因为我们也可以在localhost中使用https。
然后我们检查HttpContext.Items [“ TenantSsl”]是否为真。这是因为我们的应用程序是一个多租户应用程序,我们在其中共享代码和IIS池,但每个租户都有自己的数据库。
可能会发生一个租户拥有SSL证书而其他租户没有SSL证书的原因,这就是我们必须在租户的数据库中添加一个字段以进行检查的原因。
在执行此规则之前,我们执行承租人选择器,在其中向HttpContext.Items添加一个bool变量,指示当前承租人具有SSL证书-
最后,如果租户具有SSL证书,而该请求不是https,则我们将重定向到https页面。
可能要感谢Ray Huang,我们将这种解决方案基于他的一篇文章: https://blog.discountasp.net/3-ways-to-redirect-http-to-https-and-non-www-to-www-in-asp-net-core/