ASP.NET Core 入门教程 9、ASP.NET Core 中间件(Middleware)入门

本文涉及的产品
Serverless 应用引擎 SAE,800核*时 1600GiB*时
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: ASP.NET Core 入门教程 9、ASP.NET Core 中间件(Middleware)入门一、前言1、本教程主要内容ASP.NET Core 中间件介绍通过自定义 ASP.NET Core 中间件实现请求验签2、本教程环境信息软件/环境 说明操作系统 Windows 10SDK 2.

ASP.NET Core 入门教程 9、ASP.NET Core 中间件(Middleware)入门
一、前言
1、本教程主要内容
ASP.NET Core 中间件介绍
通过自定义 ASP.NET Core 中间件实现请求验签
2、本教程环境信息
软件/环境 说明
操作系统 Windows 10
SDK 2.1.401
ASP.NET Core 2.1.3
MySQL 8.0.x
IDE Visual Studio Code 1.32.3
浏览器 Chrome 70
VS Code插件 版本 说明
C# 1.17.1 提供C#智能感知, .NET Core 调试、编译等
vscdoe-solution-explorer 0.3.1 提供解决方案视图
本篇代码以下代码进行调整:https://github.com/ken-io/asp.net-core-tutorial/tree/master/chapter-02

3、前置知识
可能需要的前置知识

C# 委托(Delegate)
http://www.runoob.com/csharp/csharp-delegate.html

C# 扩展方法
https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/extension-methods

二、ASP.NET Core 中间件介绍
1、ASP.NET Core 中间件基本说明
当 ASP.NET Core MVC应用从Kestrel接收到请求,会建立HttpContext并交由Application来处理请求。在Application中会有一个处理该请求的通道,这就是ASP.NET Core 管道,通常称之为:请求处理管道

在这个管道中,有一系列有序处理请求的组件,就是中间件(Middleware)。

image

图中蓝色的部分可以认为是系统内置比较靠前的中间件或者我们自定义的中间件,MVC是一个特殊的中间件且通常放在最后,所以这里单独画出来

对于MVC中间件,如果请求的URL与路由匹配,那么后面的中间件均不会生效。所以MVC通常放在最后。

ASP.NET Core中会内置一些中间件,例如:身份验证、静态文件处理、MVC等。每个中间件在接受到请求后都可以选择是交由下一个中间件处理还是直接返回结果。例如:

身份验证中间件验证未通过会直接引导到登陆页
静态文件中间件判断为静态文件就会直接返回静态文件内容
所以,中间件可以理解为请求处理管道中的请求处理器。我们也可以通过自定义中间件注册到管道中来干预请求。

2、ASP.NET Core 中间件基础使用
在程序中,中间件是基于委托来构建的。在应用启动时通过IApplicationBuilder注册到通道中。

具体见启动类Startup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

app.UseMvc(routes =>
{
    //配置默认路由
    routes.MapRoute(
        name: "Default",
        template: "{controller}/{action}",
        defaults: new { controller = "Home", action = "Index" }
    );
});

}
UseDeveloperExceptionPage、UseMvc都是接口IApplicationBuilder的扩展方法。

三、使用 ASP.NET Core 中间件实现请求验签
如果你开发的API是为手机App服务的,那么你的API是一定要暴露给公网的,如果有人拿到API地址进行非法请求,获取用户信息或者是篡改数据,用户隐私、数据就会受到损害。这是很不安全的,我们可以让客户端请求的时候必须携带签名,在服务器端鉴权(验证签名)通过了再放行,这样就安全很多了。

1、创建验签中间件
在项目Ken.Tutorial.Web创建目录Middlewares,然后创建类:TokenCheckMiddleware.cs

using System;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

namespace Ken.Tutorial.Web.Middlewares
{

public class TokenCheckMiddleware
{
    private readonly RequestDelegate _next;
    public TokenCheckMiddleware(RequestDelegate requestDelegate)
    {
        this._next = requestDelegate;
    }

    public Task Invoke(HttpContext context)
    {
        //先从Url取token,如果取不到就从Form表单中取token
        var token = context.Request.Query["token"].ToString() ?? context.Request.Form["token"].ToString();
        if (string.IsNullOrWhiteSpace(token))
        {
            //如果没有获取到token信息,那么久返回token missing
            return context.Response.WriteAsync("token missing");
        }
        //获取前1分钟和当前的分钟
        var minute0 = DateTime.Now.AddMinutes(-1).ToString("yyyy-MM-dd HH:mm");
        var minute = DateTime.Now.ToString("yyyy-MM-dd HH:mm");
        //当token和前一分钟或当前分钟任一时间字符串的MD5哈希一致,就认为是合法请求
        if (token == MD5Hash(minute) || token == MD5Hash(minute0))
        {
            return _next.Invoke(context);
        }
        //如果token未验证通过返回token error
        return context.Response.WriteAsync("token error");
    }

    public string MD5Hash(string value)
    {
        using (var md5 = MD5.Create())
        {
            var result = md5.ComputeHash(Encoding.ASCII.GetBytes(value));
            var strResult = BitConverter.ToString(result);
            return strResult.Replace("-", "");
        }
    }
}

}
由于是侧重自定义中间件,所有验签的逻辑就写的非常简单,如果实际项目使用,可以按照自己需求调整

2、创建扩展方法
在Middlewares目录下新建类:MiddlewareExtension.cs

using Microsoft.AspNetCore.Builder;

namespace Ken.Tutorial.Web.Middlewares
{

public static class MiddlewareExtension
{
    public static IApplicationBuilder UseTokenCheck(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<TokenCheckMiddleware>();
    }
}

}
这里我们通过扩展方法,将TokenCheckMiddleware挂在接口IApplicationBuilder上

3、中间件注册/引用
在启动类Startup.cs的Configure方法中注册/引用中间件

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{

//省略部分代码

app.UseTokenCheck();

app.UseMvc(routes =>
{
    //省略路由配置代码
});

}
如果你觉得扩展方法有点多余,也可以直接使用UseMiddleware方法注册

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{

//省略部分代码

app.UseMiddleware<TokenCheckMiddleware>();

app.UseMvc(routes =>
{
    //省略路由配置代码
});

}
这里要注意的是,如果你是一个MVC应用,请一定要把MVC这个中间件作为最后一个注册。因为中间件是按照注册顺序被调用的。如果放在MVC之后,请求的URL也有对应路由适配,那么整个请求已经被MVC接管。后面的中间件就不会被调用了。

4、验签中间件测试
启动应用,然后验证不同情况下的访问结果

URL Response
localhost:5001 token missing
localhost:5001?token=test token error
localhost:5001?token=3D76FEA1D0ADD0C7639B73023436C6EA Hello World ! -ken.io
为了方便测试,MD5哈希的值我们可以在线生成:ttp://tool.chinaz.com/tools/md5.aspx

把当前分钟,例如:2019-03-27 23:23 通过MD5在线生成那就是3D76FEA1D0ADD0C7639B73023436C6EA

四、备注
本文代码示例
https://github.com/ken-io/asp.net-core-tutorial/tree/master/chapter-09

本文参考
https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore-2.1

延伸阅读
https://www.cnblogs.com/artech/p/inside-asp-net-core-pipeline.html

本文首发于我的独立博客:https://ken.io/note/asp.net-core-tutorial-middleware

相关文章
|
3天前
|
开发框架 搜索推荐 前端开发
【.NET全栈】ASP.NET开发Web应用——Web部件技术
【.NET全栈】ASP.NET开发Web应用——Web部件技术
|
24天前
|
开发框架 JSON .NET
|
1月前
|
SQL 开发框架 .NET
(20)ASP.NET Core EF创建模型(必需属性和可选属性、最大长度、并发标记、阴影属性)
(20)ASP.NET Core EF创建模型(必需属性和可选属性、最大长度、并发标记、阴影属性)
|
1月前
|
Linux C# C++
【.NET Developer】创建ASP.NET Core Blazor项目并打包为Linux镜像发布到Azure应用服务
本文介绍了如何使用VS2019和.NET框架创建一个Blazor应用,并将其部署到Azure应用服务。首先,Blazor是一个使用C#而非JavaScript构建交互式Web UI的框架,支持共享服务器和客户端应用逻辑,以及与Docker和Azure集成。任务包括创建Blazor项目,配置Dockerfile为Linux容器,本地测试,发布到Azure Container Registry (ACR),然后在Azure App Service for Container上部署。在部署过程中,需确保Docker设置正确,开启ACR的Admin访问权限,并监控镜像拉取和容器启动日志。
|
2月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
118 0
|
2月前
|
开发框架 前端开发 JavaScript
JavaScript云LIS系统源码ASP.NET CORE 3.1 MVC + SQLserver + Redis医院实验室信息系统源码 医院云LIS系统源码
实验室信息系统(Laboratory Information System,缩写LIS)是一类用来处理实验室过程信息的软件,云LIS系统围绕临床,云LIS系统将与云HIS系统建立起高度的业务整合,以体现“以病人为中心”的设计理念,优化就诊流程,方便患者就医。
47 0
|
2月前
|
开发框架 前端开发 .NET
C# .NET面试系列六:ASP.NET MVC
<h2>ASP.NET MVC #### 1. MVC 中的 TempData\ViewBag\ViewData 区别? 在ASP.NET MVC中,TempData、ViewBag 和 ViewData 都是用于在控制器和视图之间传递数据的机制,但它们有一些区别。 <b>TempData:</b> 1、生命周期 ```c# TempData 的生命周期是短暂的,数据只在当前请求和下一次请求之间有效。一旦数据被读取,它就会被标记为已读,下一次请求时就会被清除。 ``` 2、用途 ```c# 主要用于在两个动作之间传递数据,例如在一个动作中设置 TempData,然后在重定向到另
184 5
|
2月前
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
|
11月前
|
存储 开发框架 前端开发
[回馈]ASP.NET Core MVC开发实战之商城系统(五)
经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,banner条,友情链接,降价促销,新品爆款】,商品列表页面,商品详情等功能的开发,今天继续讲解购物车功能开发,仅供学习分享使用,如有不足之处,还请指正。
142 0
|
12月前
|
开发框架 前端开发 .NET
[回馈]ASP.NET Core MVC开发实战之商城系统(三)
[回馈]ASP.NET Core MVC开发实战之商城系统(三)
81 0