ASP.NET Core 6框架揭秘实例演示[36]:HTTPS重定向

这篇具有很好参考价值的文章主要介绍了ASP.NET Core 6框架揭秘实例演示[36]:HTTPS重定向。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

HTTPS是确保传输安全最主要的手段,并且已经成为了互联网默认的传输协议。不知道读者朋友们是否注意到当我们利用浏览器(比如Chrome)浏览某个公共站点的时候,如果我们输入的是一个HTTP地址,在大部分情况下浏览器会自动重定向到对应HTTPS地址。这一特性源于浏览器和服务端针对HSTS(HTTP Strict Transport Security)这一HTTP规范的支持。ASP.NET利用HstsMiddleware和HttpsRedirectionMiddleware这两个中间件提供了对HSTS的实现。(本文提供的示例演示已经同步到《ASP.NET Core 6框架揭秘-实例演示版》)

[S2401]构建HTTPS站点(源代码)
[S2402]HTTPS终结点重定向(源代码)
[S2403]注册HstsMiddleware中间件(源代码)
[S2404]设置HSTS配置选项(源代码)

[S2401]构建HTTPS站点

虽然目前绝大部分的公共站点都提供了HTTPS终结点,但是由于用户多年养成的习惯,以及客户端(以浏览器为主的User Agent)提供的一些自动化行为,导致针对站点的初始请求依然采用HTTP协议,所以站点还是会提供一个HTTP终结点。为了尽可能地采用HTTPS协议进行通信,“国际互联网工程组织(IETF)”制定了一份名为“HSTS(HTTP Strict Transport Security)”的安全规范或者协议,ASP.NET针对HSTS的实现是由THstsMiddleware和HttpsRedirectionMiddleware这两个中间件来完成的。接下来我们利用一个简单的实例演示来介绍HSTS旨在解决的问题,以及针对这两个中间件的使用。

HTTPS站点会绑定一张证书,并利用证书提供的密钥对(公钥/私钥对)在前期通过协商生成一个用来对传输内容进行加解密的密钥。HTTPS站点绑定的证书相当于该站点的“身份证”,它解决了服务端认证(确定当前访问的不是一个钓鱼网站)的问题。我们之所以能够利用证书来确定站点的正式身份,源于证书具有的两个特性:第一,证书不能篡改,附加了数字签名的证书可以很容易地确定当前的内容是否与最初生成时一致;第二,证书由权威机构签发,公共站点绑定的证书都是从少数几个具有资质的提供商购买的。

我们演示的程序涉及的通信仅限于本机范围,并不需要需要真正地从官方渠道去购买一张证书,所以我们选择创建一个“自签名”证书。自签名证书的创建可以采用多种方式,我们采用如下的方式在PowerShell中执行New-SelfSignedCertificate命令创建了针对“artech.com”,“blog.artech.com”和“foobar.com”域名的三张证书。

New-SelfSignedCertificate -DnsName artech.com -CertStoreLocation "Cert:\CurrentUser\My"
New-SelfSignedCertificate -DnsName blog.artech.com
    -CertStoreLocation "Cert:\CurrentUser\My"
New-SelfSignedCertificate -DnsName foobar.com -CertStoreLocation "Cert:\CurrentUser\My"

在执行New-SelfSignedCertificate命令的时候,我们利用-CertStoreLocation参数为生成的证书指定了存储位置。证书在Windows系统下是针对“账号类型”进行存储的,具体的账号分为如下三种类型,证书总是存储在某种账户类型下某个位置。对于生成在自签名证书,我们将存储位置设置为“Cert:\CurrentUser\My”,意味它们最终会存储在当前用户账户下的“个人(Personal)”存储中。

  • 当前用户账户(Current user account)
  • 机器账户(Machine account)
  • 服务账户(Service account)

我们可以利用Certificate MMC(Microsoft Management Console)查看生成的这三张证书。具体的做法是执行mmc命名开启一个MMC对话框,并选择菜单“File>Add/Remove Snap-In...”开启Snap-In窗口,在列表中选择“Certificate”选项。在弹出的证书存储类型对话框架中,我们选择“Current user account”选项。在最终开启的证书管理控制台上,我们可以在Personal存储节点中看到如图25-1所示的三张证书。

ASP.NET Core 6框架揭秘实例演示[36]:HTTPS重定向

图1 手工创建的证书

由于我们创建的是三张“自签名”的证书,也就是自己给自己签发的证书,在默认情况下自然不具有广泛的信任度。为了解决这个问题,我们可以将它们导入到“Trusted Root Certification Authorities”存储节点中,这里存储的是代表信任签发机构的证书。我们以文件的形式将证书从“Personal”导出,然后再将证书文件导入到这里。注意在导出证书时应该选择“导出私钥”选项。为了能够通过证书绑定的域名访问站点,我们在hosts文件中将它们映射到本地IP地址(127.0.0.1)。

127.0.0.1 artech.com
127.0.0.1 blog.artech.com
127.0.0.1 foobar.com

在完成了域名映射、证书创建并解决了证书的“信任危机”之后,我们创建一个ASP.NET程序,并为注册的Kestrel服务器添加针对HTTP和HTTPS协议的终结点。如下面的代码片段所示,我们调用IWeHostBuilder接口的UseKestrel扩展方法添加的终结点采用默认端口(80和443),其中HTTPS终结点会利用SelelctCertificate方法根据提供的域名选择对应的证书,为“/{foobar?}”路径注册的终结点会将代表协议类型的Scheme作为响应内容。

using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using System.Net;
using System.Security.Cryptography.X509Certificates;

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseKestrel (kestrel =>
{
    kestrel.Listen(IPAddress.Any, 80);
    kestrel.Listen(IPAddress.Any, 443, listener => listener.UseHttps(https => https.ServerCertificateSelector = SelelctCertificate));
});

var app = builder.Build();
app.MapGet("/{foobar?}", (HttpRequest request) => request.Scheme);
app.Run();

static X509Certificate2? SelelctCertificate(ConnectionContext? context,string? domain)
    => domain?.ToLowerInvariant() switch
    {
        "artech.com" => CertificateLoader.LoadFromStoreCert("artech.com", "My", StoreLocation.CurrentUser, true),
        "blog.artech.com" => CertificateLoader.LoadFromStoreCert("blog.artech.com", "My", StoreLocation.CurrentUser, true),
        "foobar.com" => CertificateLoader.LoadFromStoreCert("foobar.com", "My", StoreLocation.CurrentUser, true),
        _ => throw new InvalidOperationException($"Invalid domain '{domain}'.")
    };

程序启动之后,我们可以三个映射的域名已HTTP或者HTTPS的方式来访问它。图2示的就是使用域名“artech.com”分别发送HTTP和HTTPS请求后得到的结果。对于针对HTTP终结点的访问,浏览器还给予了一个“不安全(Not secure)”的警告。

ASP.NET Core 6框架揭秘实例演示[36]:HTTPS重定向

图2 访问HTTP和HTTPS终结点

[S2402]HTTPS终结点重定向

从安全的角度来讲,我们肯定是希望用户的每个请求指向的都是HTTPS终结点,但是我们不可能要求用户在地址栏输入的URL都以“https”作为前缀,这个问题可以通过服务端以重定向的方式来解决。如图3所示,如果服务端接收到一个HTTP请求,它立即回复一个状态码为307的临时重定向响应,并将重定向地址指向对应的HTTPS终结点,那么浏览器会自动对新的HTTPS终结点重新发起请求。

ASP.NET Core 6框架揭秘实例演示[36]:HTTPS重定向

图3 访问HTTP和HTTPS终结点

上述针对HTTPS终结点的自动重定向可以利用HttpsRedirectionMiddleware中间件来完成,我们可以按照如下的方式调用UseHttpsRedirection扩展方法来注册这个中间件,该中间件依赖的服务由AddHttpsRedirection扩展方法进行注册,我们在调用这个方法的同时对HTTPS终结点采用的端口号(443)进行了设置。

...
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseKestrel (kestrel =>
{
    kestrel.Listen(IPAddress.Any, 80);
    kestrel.Listen(IPAddress.Any, 443, listener => listener.UseHttps(https => https.ServerCertificateSelector = SelelctCertificate));
});
builder.Services.AddHttpsRedirection(options => options.HttpsPort = 443);

var app = builder.Build();
app.UseHttpsRedirection();
app.MapGet("/{foobar?}", (HttpRequest request) => request.Scheme);
app.Run();
...

改动后的程序启动后,如果我们请求“http://artech.com/foobar”这个URL,会自动被重定向到到新的地址“https://artech.com/foobar”。如下所示的是这个过程涉及到的两轮HTTP事务的请求和响应报文(S2402)。

GET http://artech.com/foobar HTTP/1.1
Host: artech.com

HTTP/1.1 307 Temporary Redirect
Content-Length: 0
Date: Sun, 19 Sep 2021 11:57:56 GMT
Server: Kestrel
Location: https://artech.com/foobar
GET https://artech.com/foobar HTTP/1.1
Host: artech.com

HTTP/1.1 200 OK
Date: Sun, 19 Sep 2021 11:57:56 GMT
Server: Kestrel
Content-Length: 5

https

[S2403]注册HstsMiddleware中间件

按照目前互联网的安全标准来看,以明文传输的HTTP请求都是不安全的,所以上述的利用HttpsRedirectionMiddleware中间件在服务端回复一个307响应将客户端重定向到HTTPS终结点的解决方案并没有真正的解决问题,因为浏览器后续还是有可能持续发送HTTP请求。虽然HTTP是无状态的传输协议,但是浏览器可以有“记忆”。如果能够让应用以响应报头的形式告诉浏览器:在未来一段时间内针对当前域名的后续请求都应该采用HTTPS,浏览器将此信息保存下来,即使用户输入的是HTTP地址,那么它也采用HTTPS的方式与服务端进行交互。

其实这就是HSTS(HTTP Strict Transport Security)的意图。HSTS可能是所有HTTP规范家族中最简单的一个了,因为整个规范只定义了上述这个用来传递HTTPS策略的响应报头,它被命名为“Strict-Transport-Security”。服务端可以利用这个报头告诉浏览器后续当前域名应该采用HTTPS进行访问,并指定采用这个策略的时间范围。如果浏览器遵循HSTS协议,那么针对同一站点的后续请求将全部采用HTTPS传输,具体流程如图4所示。

ASP.NET Core 6框架揭秘实例演示[36]:HTTPS重定向

图4 采用HSTS协议

HSTS涉及的这个 “Strict-Transport-Security”响应报头可以借助HstsMiddleware中间件进行发送。对于前面演示的实例来说,我们可以按照如下的方式调用UseHsts扩展方法注册这个中间件。

...
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseKestrel (kestrel =>
{
    kestrel.Listen(IPAddress.Any, 80);
    kestrel.Listen(IPAddress.Any, 443, listener => listener.UseHttps(https => https.ServerCertificateSelector = SelelctCertificate));
});
builder.Services.AddHttpsRedirection(options => options.HttpsPort = 443);

var app = builder.Build();
app
    .UseHttpsRedirection()
    .UseHsts();
app.MapGet("/{foobar?}", (HttpRequest request) => request.Scheme);
app.Run();
...

当我们启动改动后的演示程序之后,针对“artech.com”的第一个HTTP请求依然会被正常发送出去。服务端注册的HttpsRedirectionMiddleware中间件会将请求重定向到对应的HTTPS终结点,此时UseHsts中间件会在响应中添加 如下所示的“Strict-Transport-Security”报头。

HTTP/1.1 200 OK
Date: Sun, 19 Sep 2021 12:59:37 GMT
Server: Kestrel
Strict-Transport-Security: max-age=2592000
Content-Length: 5

https

上述的“Strict-Transport-Security”报头利用max-age属性将采用HTTPS策略的有效时间设置成2592000秒(一个月)。这是一个“滑动时间”,浏览器每次在接收到携带此报头的响应之后都会将有效截止时间设置到一个月之后,这意味着对于经常访问的站点来说,HTTPS策略将将永不过期。

浏览器会对此规则进行持久化存储,后续针对“artech.com”域名的请求将一直采用HTTPS传输方式。对于Chrome浏览器来说,其内部依然采用客户端重定向的方式实现从HTTP到HTTPS终结点的切换。具体来说,如果用户指定的是HTTP地址,Chrome会在内部生成一个指向HTTPS终结点的307重定向响应,所以我们利用Chrome提供的网络监测工具看到的还是如图25-5所示的两次报文交换,但是第一个请求并未被真的发送出去。这个内部生成的307响应携带会这个值为“HSTS”的Non-Authoritative-Reason报头。

ASP.NET Core 6框架揭秘实例演示[36]:HTTPS重定向

图5 Chrome通过内部生成一个307响应实现HTTPS重定向

Chrome提供了专门的页面来查看和管理针对某个域名的HSTS设置,我们只需要在地址栏里输入“chrome://net-internals/#hsts”这个URL就可以进入这个针对HSTS/PKP(Public Key Pinning)的域名安全策略管理页面。我们可以在该页面中查询、添加和删除针对某个域名的HSTS安全策略。针对artech.com这个域名的安全策略显示在图6中。

ASP.NET Core 6框架揭秘实例演示[36]:HTTPS重定向

图6 某个域名的安全策略

[S2404]设置HSTS配置选项

到目前为止,我们利用HttpsRedirectionMiddleware中间件将HTTP请求重定向到HTTPS终结点,在利用HstsMiddleware中间件通过在响应中添加Strict-Transport-Security报头告诉客户端后续请求也应该采用HTTPS传输协议,貌似已经很完美地解决我们面临的安全问题。但是不要忘了,第一个请求采用的依旧是HTTP协议,黑客依旧可能劫持该请求并将用户重定向到钓鱼网站。

为了让浏览器针对某个域名发出的第一个请求也无条件采用HTTPS传输方式,我们必须在全网范围内维护一个统一的域名列表。当浏览器在安装的时候会将这个列表保存在本地,并在每次启动的时候预加载此列表,所以我们称这个域名列表为“HSTS Preload List”。如果需要将某个域名添加到HSTS预加载列表中,我们可以利用https://hstspreload.org站点提交申请,

ASP.NET Core 6框架揭秘实例演示[36]:HTTPS重定向

图7 HSTS预加载列表提交官网

通过图7所示的这个站点提交的预加载域名列表最初专供Chrome使用的,但是目前大部分主流浏览器(Firefox, Opera, Safari, IE 11 和Edge)也都会使用这个列表。也正式因为这个列表会被广泛地使用,官方会对我们提交的域名进行严格的审核,并且审核期期还不短(一到两个月)。审核通过后,提交的域名还不会立即生效,还要等到新版本的浏览器发布的时候。有资质的站点必须满足如下几个条件:

  • 拥有一张有效的证书。
  • 对于采用80端口的HTTP终结点,必须存在对应的采用相同主机名称(域名)的HTTPS终结点。
  • 所有子域名均支持HTTPS。
  • 对于针对基础域名(Base Domain)的HTTPS请求,接收到的响应必须包含“Strict-Transport-Security”这个HSTS报头,并且该报头内容满足如下条件:
    • max-age属性代表的有效时间在一年(含一年)以上,即大于31536000秒;
    • 包含includeSubDomains指令,该指令表示HSTS策略会应用到所有的子域名上;
    • 必须包含preload指令。
    • 如果需要对HTTPS请求实施重定向,重定向的响应本身也必须包含这样的HSTS报头。

从上面这个列表可以看出,HSTS涉及的“Strict-Transport-Security”响应报头除了包含必需的表示有效期限的max-age属性之外,还包含includeSubDomains和preload两个指令。它们都定义在对应的HstsOptions配置选项中,我们可以按照如下的方式调用AddHsts扩展方法并利用指定的Action<HstsOptions>委托进行设置。如下的演示程序对HstsOptions配置选项的四个属性进行了设置。

...
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseKestrel(kestrel =>
{
    kestrel.Listen(IPAddress.Any, 80);
    kestrel.Listen(IPAddress.Any, 443, listener => listener.UseHttps(
       https => https.ServerCertificateSelector = SelelctCertificate));
});

builder.Services.AddHttpsRedirection(options => options.HttpsPort = 443);
builder.Services.AddHsts(options => {
    options.MaxAge = TimeSpan.FromDays(365);
    options.IncludeSubDomains = true;
    options.Preload = true;
    options.ExcludedHosts.Add("foobar.com");
 });

var app = builder.Build();
app
    .UseHttpsRedirection()
    .UseHsts();
app.MapGet("/{foobar?}", (HttpRequest request) => request.Scheme);
app.Run();
...

由上面这个应用返回的响应都将包含如下这个HSTS报头。由于includeSubDomains指令的存在,如果之前发生过针对artech.com域名的请求,那么针对其子域名blog.artech.com的请求也将自动切换到HTTPS传输方式。虽然具有preload指令,但是我们的站点并不能添加到HSTS预加载列表中,所以此设定起不到任何作用。由于域名 “foobar.com” 被显式地排除在HSTS站点之外,浏览器不会将针对它的HTTP请求转换成HTTPS传输方式,由于注册了HttpsRedirectionMiddleware中间件,HTTP请求还是会以客户端重定向的方式切换到对应的HTTPS终结点。文章来源地址https://www.toymoban.com/news/detail-466896.html

strict-transport-security: max-age=31536000; includeSubDomains; preload

到了这里,关于ASP.NET Core 6框架揭秘实例演示[36]:HTTPS重定向的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ASP.NET Core使用JWT+标识框架(identity)实现登录验证

    最近阅读了《ASP.NET Core 技术内幕与项目实战——基于DDD与前后端分离》(作者杨中科)的第八章,对于Core入门的我来说体会颇深,整理相关笔记。 JWT:全称“JSON web toke”,目前流行的跨域身份验证解决方案; 标识框架(identity):由ASP.NET Core提供的框架,它采用RBAC(role

    2024年02月11日
    浏览(33)
  • asp.net core 框架搭建2-搭建MVC后台管理系统

    作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/131458964 asp.net core 框架搭建2-搭建MVC后台管理系统 ,本文章介绍asp.net core框架搭建,然后开发一个后台管理系统,将一步步带着大家,实现目标。所有操作过程将展现在本篇文章,下面咋们一起来实现它吧。 使

    2024年02月12日
    浏览(32)
  • 【ASP.NET Core 基础知识】--MVC框架--Models和数据绑定

    Models和数据绑定在ASP.NET Core MVC中扮演着关键的角色,对于构建强大、灵活和可维护的Web应用程序至关重要。这一节我们就来讲一下。 一、Models 1.1 Models的定义和作用 在ASP.NET Core MVC中,Model是应用程序中用于表示数据结构和业务逻辑的一种抽象。Models充当了MVC(Model-View-Contr

    2024年01月23日
    浏览(36)
  • asp.net core框架搭建1-搭建webapi,对数据增删改查接口模板(附源码)

    作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/131458922 asp.net core 框架搭建2-搭建webapi ,本文章介绍asp.net core webapi框架搭建,然后开发增删改查和工具接口,将一步步带着大家,实现目标。所有操作过程将展现在本篇文章,下面咋们一起来实现它吧。 asp.ne

    2024年02月13日
    浏览(38)
  • dotnet 简单方法在一个进程内同时跑起 WPF 和 ASP.NET Core 框架

    从设计架构上,无论是 WPF 还是 ASP.NET Core 框架,都是在 dotnet 运行时上层的应用,两个框架处于平级的结构。理论上讲,两个平级的框架只要不存在特殊的情况,都是能够相容存在的。本文将和大家介绍一个非常简单的方法,在一个进程内同时跑起 WPF 和 ASP.NET Core 框架 在一

    2024年04月26日
    浏览(33)
  • 如何在ASP.NET Core应用中实现与第三方IoC/DI框架的整合?

    我们知道整个ASP.NET Core建立在以ServiceCollection/ServiceProvider为核心的DI框架上,它甚至提供了扩展点使我们可以与第三方DI框架进行整合。对此比较了解的读者朋友应该很清楚,针对第三方DI框架的整合可以通过在定义Startup类型的ConfigureServices方法返回一个ServiceProvider来实现。但

    2024年02月09日
    浏览(41)
  • 《深入浅出.NET框架设计与实现》笔记6.2——ASP.NET Core应用程序多种运行模式之二——IIS 服务承载

     ASP.NET Core应用程序可以在多种运行模式下运行,包括自宿主(Self-Hosting)、IIS服务承载、桌面应用程序、服务承载。 因此选择和时的模式很重要。 IIS 服务承载 将 ASP.NET Core 应用程序托管在 Internet Information Services (IIS) 中。 利用 IIS 提供的高级功能,如负载均衡、HTTPS 支持和

    2024年04月26日
    浏览(33)
  • Taurus .Net Core 微服务开源框架:Admin 插件【4-1】 - 配置管理-Kestrel【含https启用】

    继上篇:Taurus .Net Core 微服务开源框架:Admin 插件【3】 - 指标统计管理 本篇继续介绍下一个内容: 界面图如下: 双击节点即可进入修改模式,如:   修改说明:   节点说明:默认显示的是 Mvc 的配置界面。 本节先讲 Kestrel 相关的配置项: 界面如下:  配置说明:经过对

    2024年02月11日
    浏览(33)
  • ASP.Net Core Web API结合Entity Framework Core框架(API的创建使用,接口前端权限设置,前端获取API的Get,post方法)(程序包引用以及导入数据库)

    目录 1. Web Api 程序包引用 2. Web Api 的创建与Http类型的介绍 2.1 ASP.Net Core Web API项目的创建 2 .2  API接口的创建 2.3 HttpGet和HttpPost类型的区别 3.接口权限设置 4.HttpGet方法和HttpPOst方法 5.前端中用HttpGet/Poset获取接口数据 6.EF框架——配置数据库链接字符串(即将数据库中的表导入项

    2024年02月08日
    浏览(52)
  • ASP.NET Core教程:ASP.NET Core 程序部署到Windows系统

    本篇文章介绍如何将一个ASP.NET Core Web程序部署到Windows系统上。这里以ASP.NET Core WebApi为例进行讲解。首先创建一个ASP.NET Core WebApi项目,使用默认的Values控制器,这里使用Visual Studio 2019创建一个ASP.NET Core 3.1d的WebApi项目。 创建新项目的时候选项ASP.NET Core Web应用程序,如下图所

    2023年04月08日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包