一、前言

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)。

图中蓝色的部分可以认为是系统内置比较靠前的中间件或者我们自定义的中间件,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" }
);
});
}

UseDeveloperExceptionPageUseMvc都是接口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(-).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.csConfigure方法中注册/引用中间件

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://www.cnblogs.com/ken-io/p/aspnet-core-tutorial-middleware.html

如有侵权,请告知

ASP.NET Core 入门笔记10,ASP.NET Core 中间件(Middleware)入门的更多相关文章

  1. ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则

    ASP.NET MVC 学习笔记-7.自定义配置信息   ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...

  2. ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现

    ASP.NET MVC 学习笔记-2.Razor语法   1.         表达式 表达式必须跟在“@”符号之后, 2.         代码块 代码块必须位于“@{}”中,并且每行代码必须以“: ...

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

    一.前言 1.本教程主要内容 ASP.NET Core 中间件介绍 通过自定义 ASP.NET Core 中间件实现请求验签 2.本教程环境信息 软件/环境 说明 操作系统 Windows 10 SD ...

  4. ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用

    Ajax的全名为:Asynchronous Javascript And XML(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术.Ajax技术首先向Web服务器发送 ...

  5. ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础

    ASP.NET MVC在原来ASP.NET的基础上抛弃了基于页面的架构风格,使用了全新的MVC(模型-视图-控制器)架构的一种技术. 目前,它和ASP.NET都共存在.NET Framework之上. ...

  6. Python入门笔记(10):字典

    一.映射类型 我理解中的映射类型是:键值对的关系,键(key)映射值(value),且它们是一对多的关系.字典是Python唯一的映射类型. 扩展1:哈希表一种数据结构,值是根据相关的键进行数据存储的 ...

  7. ASP.NET Core 入门笔记9,ASP.NET Core + Entity Framework Core 数据访问入门

    一.前言 1.本教程主要内容 ASP.NET Core MVC 集成 EF Core 介绍&操作步骤 ASP.NET Core MVC 使用 EF Core + Linq to Entity ...

  8. ASP.NET Core 入门笔记5,ASP.NET Core MVC控制器入门

    摘抄自https://www.cnblogs.com/ken-io/p/aspnet-core-tutorial-mvc-controller-action.html 一.前言 1.本教程主要内容 A ...

  9. 路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) ASP.NET WebApi技术从入门到实战演练 C#面向服务WebService从入门到精通 DataTable与List<T>相互转换

    路由其实也可以很简单-------Asp.net WebAPI学习笔记(一)   MVC也好,WebAPI也好,据我所知,有部分人是因为复杂的路由,而不想去学的.曾经见过一位程序猿,在他MVC程序中, ...

随机推荐

  1. Mac OS 系统开发环境的一些坑

    最近换 Mac OS 系统开发,运行项目时遇到各种报错,记录下: 1.拉取项目后,需要安装依赖 npm install ,提示需要安装 xcode,报错如下. 从官网下载 xcode 时提示要更新最新 ...

  2. C语言位运算题解

    #include <stdio.h> #include <stdlib.h> #include <string.h> //#define NONBLANK 1 ma ...

  3. PHP mysqli_fetch_lengths() 函数

    mysqli_fetch_lengths() 函数返回结果集中的字段长度. <?php // 假定数据库用户名:root,密码:123456,数据库:RUNOOB $con=mysqli_con ...

  4. 一个参数既可以是const还可以是volatile

    可以的,例如只读的状态寄存器.它是volatile因为它可能被意想不到地改变.它是const因为程序不应该试图去修改它. 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器 ...

  5. 人脸检测之Haar-like,Adaboost,级联(cascade)

    最新版本整理完毕,见: http://face2ai.com/MachineLearning-Haar-like-Adaboost-cascade 0:写在前面的话           写在前面的牢骚 ...

  6. Java线程之join

    简述 Thread类的join方法用来使main线程进入阻塞状态,进而等待调用join方法的线程执行,join有三个重载方法: public final void join() 使主线程进入阻塞状态, ...

  7. 记一次maxwell报错:Couldn't find table 'violation_info' in database och_evcard_data

    往常maxwell是正常跑的,但是突然今天报错: Couldn't find table 'violation_info' in database och_evcard_data 而且这个库和这个表, ...

  8. selenium知识点

    1. 导包 from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from se ...

  9. 笔记一(固件、BIOS、UEFI)

    1.固件 固件一般是指保存在ROM中的程序和数据,通过固件操作系统按照标准的设备驱动实现特定机器的运行. 简单来讲,固件就是固化在ROM的软件,当然也可以通过特定的工具进行升级. MP3.MP4.手机 ...

  10. AtomicReference、AtomicStampedReference 和 AtomicMarkableReference

    这三个都是自 JDK1.5 开始加入到 java.util.concurrent.atomic 下面的.他们都可以在 lock-free 的情况下以原子的方式更新对象引用. 一.AtomicRefer ...