在一个控制器上强制执行 https,在另一个控制器上强制执行 http
Posted
技术标签:
【中文标题】在一个控制器上强制执行 https,在另一个控制器上强制执行 http【英文标题】:Enforce https on one controller and http on the other 【发布时间】:2018-08-19 10:38:33 【问题描述】:我正在使用 ASP.NET 核心 2.1, 我正在寻找一种在一个控制器上强制执行 https 并在另一个控制器上强制执行 http 的方法。
以下文档显示了如何为整个 ASP.NET 核心强制实施 HTTPS,而不是对单个控制器强制实施 HTTPS。
https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl?view=aspnetcore-2.1&tabs=visual-studio
【问题讨论】:
【参考方案1】:一种方法是使用两种操作过滤器:一种用于强制执行 HTTPS 重定向,另一种用于允许 HTTP 请求。第一个将在全球范围内注册,第二个仅用于您希望允许 HTTP 流量的控制器/操作。举个例子:
[AllowHttp]
public class HomeController : Controller
其中AllowHttp
定义为:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
// Inheriting from ActionFilterAttribute allows this to show
// up in the ActionExecutingContext.Filters collection.
// See the global filter's implementation.
public class AllowHttpAttribute : ActionFilterAttribute
接下来,全局过滤器:
// Needed for the GetEncodedUrl() extension method.
using Microsoft.AspNetCore.Http.Extensions;
public class RedirectToHttpsActionFilter : ActionFilterAttribute
public override void OnActionExecuting(ActionExecutingContext context)
if (context.Filters.Any(x => x is AllowHttpAttribute))
return;
if (!context.HttpContext.Request.IsHttps)
var insecureUri = context.HttpContext.Request.GetEncodedUrl();
var secureUri = insecureUri.Replace("http://", "https://");
// As you're likely trying this out locally, you'll need to specify
// the port to redirect to as well. You won't need this on production.
// Change the first port to your HTTP port and the second to your HTTPS port.
secureUri = secureUri.Replace(":49834", ":44329");
context.Result = new RedirectResult(secureUri);
最后,您必须在 Startup.cs
中全局注册过滤器:
services.AddMvc(options =>
options.Filters.Add(new RedirectToHttpsActionFilter());
);
我相信您可以通过 URL 重写来实现相同的效果,但是在您可能更改控制器路由的情况下,这将继续工作而无需干预。
【讨论】:
谢谢,我还以为asp.net core内置了更直接的方法。关于“全局过滤器”,它是我需要在项目中制作的常规课程吗? @Dror 不客气,没错。为它创建一个新类。ActionFilterAttribute
位于 Microsoft.AspNetCore.Mvc.Filters
命名空间中。
Gotcha,不能真正在本地测试它,因为在 IIS express 上它在任何情况下都使用 HTTP。我可以在本地忽略此过滤器吗?另一方面,在生产中它似乎确实有效!
@Dror 实际上是个好问题,但也许最好的方法是为 IIS Express 启用 SSL。这样,您就可以在更接近生产的环境中工作。如果您转到 Web 项目的属性 -> 调试 -> Web 服务器设置 -> 启用 SSL,那应该会为您完成。不过,您需要在本地包含端口重定向。
@Dror 其实我刚刚发现可以通过ConfigureServices
方法获取环境,在开发环境中避免注册过滤器。见:***.com/a/46551596/729541以上是关于在一个控制器上强制执行 https,在另一个控制器上强制执行 http的主要内容,如果未能解决你的问题,请参考以下文章
Objective-C 以编程方式在另一个视图控制器上显示视图控制器