在一个控制器上强制执行 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 以编程方式在另一个视图控制器上显示视图控制器

如何在另一个视图控制器上向 UInavigationcontroller 显示完整的选定表格单元格

Swift函数在另一个函数完成后执行

在另一个视图控制器展开 segue 后重新加载 UIView 数据上的自定义 tableview