从 ASP.NET 到 .NET Core 的 DelegateHandler

2023-12-30

在一个旧的 asp.net 项目中,我有一个类实现DelegatingHandler我为每条路线设置的:

public class AdminSecurityMessageHandler : DelegatingHandler
{
    private readonly HttpConfiguration _config;

    public AdminSecurityMessageHandler(HttpConfiguration config)
    {
        if (config == null)
        {
            throw new ArgumentNullException("config");
        }
        _config = config;
    }

    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var repository = (IUserRepository)_config.DependencyResolver.GetService(typeof(IUserRepository));
        var accessTokener = (IAccessTokener)_config.DependencyResolver.GetService(typeof(IAccessTokener));

        if (!request.Headers.Contains(AccessTokener.CallerId))
        {
            return Unauthorized(String.Empty);
        }

        var guid = request.Headers.GetValues(AccessTokener.CallerId).FirstOrDefault();
        var user = repository.GetByGuid(guid);

        if (user == null)
        {
            return Unauthorized(String.Empty);
        }

        var result = accessTokener.CheckAccessTokenHash(user.Guid, request.Headers.Authorization.Parameter);
        switch (result)
        {
            case AccessTokenCheckerResult.Invalid:
                return Unauthorized(String.Empty);
            case AccessTokenCheckerResult.Expired:
                return Unauthorized("AccessToken.Expired");
        }

        if (!user.IsAdmin)
        {
            return Unauthorized("No admin rights");
        }

        var claims = new List<Claim>();
        claims.Add(new Claim(ClaimTypes.Name, user.Id.ToString()));
        var identity = new ClaimsIdentity(claims, "custom");
        var principal = new UserPrincipal(identity, user);
        request.GetRequestContext().Principal = principal;

        return base.SendAsync(request, cancellationToken);
    }

我需要将项目移动到.NET Core,并且在尝试注册它们时遇到一些麻烦。 我可以注册这样的简单路线:

app.UseMvc(routes => { routes.MapWebApiRoute("DefaultApi", "api/{controller}/{id?}"); });

所以问题是我应该如何实施和设置类似的东西DelegatingHandler当我在 .NET Core 中注册路由时,来自 ASP.NET? (为每条路线设置不同的处理程序)

它在 ASP.NET 中的工作原理: 注册方法在WebApiConfig class.

public static void RegisterRoutes(HttpConfiguration config, HttpMessageHandler routeHandlers, HttpMessageHandler adminRouteHandlers)
{
    .......................

    config.Routes.MapHttpRoute(
        name: "FriendsAPI",
        routeTemplate: "api/users/{id}/friends/{friendId}",
        defaults: new { controller = "Friends", friendId = RouteParameter.Optional },
        constraints: null,
        handler: routeHandlers
    );


    config.Routes.MapHttpRoute(
        name: "AdminUserBlocksApi",
        routeTemplate:
            "api/admin/user-blocks/{userId}",
        defaults: new { controller = "AdminUserBlocks", userId = RouteParameter.Optional },
        constraints: null,
        handler: adminRouteHandlers
    .......................
    );
}

既然没有DelegateHandlers in Asp.Net Core你可以尝试创建一个自定义的middleware。请参阅简化版middleware您可以使用它来满足您的要求:

public class AdminSecurityMiddleware
{
    private readonly RequestDelegate _next;
    IUserRepository userRepository; // IUserRepository should be registered for dependency injection in Startup.ConfigureServices

    public AdminSecurityMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        bool isAdminUserBlocksApiRoute; 
        //check for route here. As I know there is no elegant way to get name of the route since context.GetRouteData() returns null until mvc middleware is called.
        // probably you can check like this context.Request.Path.StartsWithSegments("/api/admin")

        if (isAdminUserBlocksApiRoute)
        {
            _userRepository = context.RequestServices.GetService<IUserRepository>();
            bool isUserAuthorized;
            // check here for Authorization
            if (!isUserAuthorized)
            {
                context.Response.Clear();
                context.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
                await context.Response.WriteAsync("Unauthorized");
                return;
            }

            // adding custom claims
            var identity = new ClaimsIdentity(new GenericIdentity("user.Id"), new[] { new Claim("user_id", "id") });
            context.User.AddIdentity(identity);
        }
        await _next.Invoke(context);
    }
}

然后将其添加到之前的管道中mvc middleware in Startup:

app.UseMiddleware<AdminSecurityMiddleware>();
app.UseMvc(routes =>
{
    ...
}

阅读有关中间件的更多信息here https://docs.asp.net/en/latest/fundamentals/middleware.html#writing-middleware

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 ASP.NET 到 .NET Core 的 DelegateHandler 的相关文章

  • 增加超时时间

    我必须增加超时时间 以下是我的代码 Private Function GetConnectionInstance As SqlConnection Dim objConn As SqlConnection Dim strConnection
  • 在 C 中声明和初始化数组

    C 有没有办法先声明然后初始化数组 到目前为止 我一直在初始化一个这样的数组 int myArray SIZE 1 2 3 4 但我需要做这样的事情 int myArray SIZE myArray 1 2 3 4 在 C99 中 您可以使
  • 设置外部应用程序焦点

    在 VB NET 中 您可以使用以下命令将焦点设置到外部应用程序 AppActivate Windows Name or AppActivate processID As Integer 现在 如果您这样做 则效果很好 Dim intNot
  • 按位非运算符

    为什么要按位运算 0 打印 1 在二进制中 不是0应该是1 为什么 你实际上很接近 在二进制中 不是0应该是1 是的 当我们谈论一位时 这是绝对正确的 然而 一个int其值为0的实际上是32位全零 将所有 32 个 0 反转为 32 个 1
  • 在 DefaultHttpContext 上使用 FeatureCollection 时,响应对象为 null

    我正在测试一些 net Core 中间件 并希望使用整个 asp net Core http 管道来运行中间件 而不是模拟它 问题是 当我使用特征集合时 不知何故 响应对象没有在 httpRequest 中设置 并且它在请求本身上是只读的
  • 有哪些 API 可在 Windows 中使用 C# 配置扬声器设置?

    我环顾了很多不同的地方 但似乎找不到一个简单的方法来做到这一点 我在 Windows 7 中有多个声卡 并使用 HDMI 将声音输出到我的 AVR 放大器 我遇到的问题是 当放大器关闭时 它会导致窗口丢失扬声器配置 所以我想做的是编写一个小
  • .NET 中 IEqualityComparer 中 GetHashCode 的作用是什么?

    我试图了解 IEqualityComparer 接口的 GetHashCode 方法的作用 下面的例子取自MSDN using System using System Collections Generic class Example st
  • 整数与双精度算术性能?

    我正在编写一个 C 类来使用整数执行 2D 可分离卷积 以获得比双对应更好的性能 问题是我没有获得真正的性能提升 这是 X 过滤器代码 对于 int 和 double 情况都有效 foreach pixel int value 0 for
  • 让 GCC/Clang 使用 CMOV

    我有一个简单的标记值联合 这些值可以是int64 ts or doubles 我正在对这些联合进行加法 但需要注意的是 如果两个参数都代表int64 t值 那么结果也应该有一个int64 t value 这是代码 include
  • 编译器在函数名称前添加下划线前缀的原因是什么?

    当我看到 C 应用程序的汇编代码时 如下所示 emacs hello c clang S O hello c o hello s cat hello s 函数名称以下划线作为前缀 例如callq printf 为什么这样做以及它有什么优点
  • 在 Asp.Net 模板中转义内联代码块

    我有一个页面 我希望在其中呈现以下 html 一个小的 JS 模板 然而 Asp NET 预处理器正在拾取 我已经设法通过文字控件来做到这一点 并在后面的代码中设置它的文本 我理想地希望将其保留在 aspx 页面中 这是我能找到的最好的解决
  • 锁定文件的一个块

    我有一个大小为 192k 的文件 我想锁定文件的中间部分 例如 我想用 c 锁定文件的 64k 128k 知道如何锁定文件的那部分吗 你需要使用锁定文件Ex http msdn microsoft com en us library win
  • 使用 HttpHandler 或 HttpModule 上传大文件?

    我有一个网络表单应用程序 它需要能够上传大文件 100MB 我打算使用 httpHandler 和 httpModule 将文件拆分为chunk 我也看过http forums asp net t 55127 aspx http forum
  • 派生类的聚合初始化

    以下代码无法使用 Visual Studio2017 或在线 GDB 进行编译 我期望它能够编译 因为迭代器只是一个具有类型的类 并且它是从公共继承的 这是不允许的还是在 VS2017 中不起作用 template
  • 即使对于新上下文,OnModelCreating 也仅调用一次

    我有多个相同但内容不同的 SQL Server 表 在编写代码优先 EF6 程序时 我尝试为每个程序重用相同的数据库上下文 并将表名称传递给上下文构造函数 然而 虽然每次都会调用构造函数 但尽管每次都是从 new 创建数据库上下文 但 On
  • 如何通过Task.ContinueWith创建传递?

    我想在原始任务结束时添加一个任务 但想保留原始结果和类型 附加任务仅用于记录目的 例如写入控制台等 例如 Task Run gt DateTime Now Hour gt 12 Hey throw new Exception Continu
  • 字符串常量之前应有非限定 ID

    我目前正在编写一个 C 应用程序 它与 math h 结合实现了振荡器 我拥有的代码应该可以很好地用于该应用程序 尝试编译目标文件 但是我遇到编译器错误 很可能与语法 等有关 我认为这与命名空间有关 错误 终端输出 User Name Ma
  • Selenium WebDriver 在按钮单击事件上无法正常工作。这里有什么问题呢?

    I am using following code to scrape data from a website I have following interface 这是 HTML div class es content div
  • 为什么 32 位 .NET 进程的引用类型的最小大小为 12 字节

    我正在读专业 Net 性能 https rads stackoverflow com amzn click com 1430244585本书有关参考类型内部结构的部分 它提到 对于 32 位 net 进程 引用类型具有 4 字节的对象头和
  • 如何使用字符串的值将字符串转换为 wstring?

    我是 C 新手 我有这个问题 我有一个名为 DATA DIR 的字符串 需要将其格式化为 wstring string str DATA DIR std wstring temp L s str Visual Studio 告诉我没有与参数

随机推荐

  • 程序崩溃,但调试诊断说这是第一次机会异常,对吗?

    也许这是正常情况 但我很困惑 我正在从 Visual Studio 运行我的 C 调试应用程序 DebugDiag 设置为自动附加到进程 我有一条规则从该 应用程序收集故障转储 并且该规则定义未配置的第一次机会异常的操作应为 无 但是当应用
  • 如何将 EL 变量传递给 JavaScript

    我有一个变量 bean name 我如何将它传递给 JavaScript 变量 我试过了var name bean name and var name bean name 但它不起作用 我的想法是将其放入隐藏输入中 就像隐藏中一样
  • Phonegap iOS:将图像下载到照片库

    是否可以下载文件 图像 并将其保存在照片库中 我知道这一点download http docs phonegap com en 2 3 0 cordova file file md html FileTransfer download方法
  • 获取整数的第 n 位

    我得到一个大整数a 和一个 相对较小的 整数n 最快的获取方式是什么n二进制表示的第 th 位 从右起 a使用原生Python 将位移到最后一个位置 屏蔽其他所有内容 bit a gt gt n 1 这假设这些位以通常的方式索引 即最低有效
  • 如何在 asp.net MVC 中压缩内容?

    如何压缩 asp net mvc 应用程序发送的输出 这是我使用的 截至目前 using System IO Compression public class CompressAttribute ActionFilterAttribute
  • 从 kpcs7 (.p7b) 文件中提取私钥和证书

    我有一个 p7b 文件 如何提取密钥和证书 我尝试过 openssl 但无法获得确切的命令 选项 Thanks PKCS 7 文件不包含私钥 至于证书 您尚未指定您使用的平台以及您的问题与编程有何关系
  • 在 Windows 上安装更新时 Electron 自动更新失败

    我有一个电子应用程序 它使用electron builder用于构建 打包和发布应用程序 我有以下自动更新代码 autoUpdater logger log autoUpdater logger transports file level
  • VBScript 打开一个对话框来选择文件路径

    目前我正在使用 vbscript 打开一个文件 如下所示 strFile C Users test file txt Set objFile objFSO OpenTextFile strFile 我想更改此设置 以便用户可以选择 导航到文
  • WPF:忽略覆盖/装饰器上的鼠标单击,但处理 MouseEnter 事件

    我真正想要的是忽略鼠标的 IsHitTestVisible 版本click事件但仍然捕获鼠标进入和离开 events 背景 每当焦点控件下方都会弹出信息叠加层 这是一项要求 因此我无权删除此行为 这是使用包含矩形形状且填充有图像画笔的装饰器
  • c# 将非常大的位图保存为 jpeg(或任何其他压缩格式)

    我目前正在处理非常大的图像 这些图像基本上是通过将许多较小的图像拼接在一起生成的 例如全景图或照片马赛克软件 为了避免内存不足的异常 内存中只有如何排列较小图像的 地图 我编写了一些代码 使用 BinaryWriter 和 LockBits
  • 如何使固定元素的内容仅在超过视口高度时才可滚动?

    我有一个div定位fixed位于网页的左侧 包含菜单和导航链接 它没有从 css 设置高度 内容决定高度 宽度是固定的 问题是如果内容太多的话div会大于窗口的高度 并且部分内容将不可见 滚动窗口没有帮助 因为位置是fixed和div不会滚
  • 如何从VB脚本确定Windows版本? [复制]

    这个问题在这里已经有答案了 可能的重复 用于查找 Windows 版本名称和服务包的 vbscript https stackoverflow com questions 4317794 a vbscript to find windows
  • 现有文件上的 java.io.FileNotFoundException

    当我尝试打开文件时出现此错误 java io FileNotFoundException D Portable 20Programs Android 20Development workspace3 XXX desktop bin Worl
  • Play 的 API 上找不到 JPA.getJPAConfig 方法

    我正在使用最新版本的 Play v 1 2 3 我的系统需要从一个数据库读取数据并将其保存到另一个数据库 我在 Play 文档中发现有一个名为 play db JPA getJPAConfig 的方法来完成这项工作 我需要在源数据库中进行本
  • 基于第三列的 pandas 数据框颜色的 Seaborn 散点图

    我有一个 pandas 数据框 其中包含 组名 结果 和 温度 列 我绘制了一个 Seaborn 群图 其中 x groupname 和 y result 它显示了分成组的结果数据 我还想做的是使用颜色图根据标记的温度对标记进行着色 例如最
  • 如何更改 VS Code 中特定单词的颜色?

    有没有办法用自定义颜色为特定单词着色 我正在查看 editor tokenColorCustomizations 但似乎没有任何暗示 我想轻松地从其他代码中辨别出一段特定的代码 例如自定义方法 例如在 javascript 中 您经常使用
  • 使用 scikit Pipeline 测试模型,但仅预处理数据一次

    假设我有一个数据管道 它进行预处理并在最后有一个估计器 现在 如果我只想在管道的最后一步更改估计器 模型 我该如何做而不再次预处理相同的数据 下面是一个代码示例 pipe make pipeline ColumnSelector colum
  • Spring 4.x/3.x (Web MVC) REST API 和 JSON2 Post 请求,如何一次性解决?

    在详细介绍之前 我知道 Stackoverflow 上已经有很多对话和相关问题 他们都以不同的方式帮助我 所以我想我将我的发现全部放在一起作为一个有组织的常见问题解答来总结我的发现 相关概念 您当然知道这些 但我只是将它们写为快速回顾 如果
  • 保留尾随空格 Sybase

    我有一大块文本数据 我将其拆分并写入多行varchar 255 表的列 有时 最后一个字符恰好是空格 当我读回这一行时 尾随空格被截断 我只得到 254 个字符 当我将下一行附加到这一行的末尾时 这会弄乱我的数据 我的代码将完整的 255
  • 从 ASP.NET 到 .NET Core 的 DelegateHandler

    在一个旧的 asp net 项目中 我有一个类实现DelegatingHandler我为每条路线设置的 public class AdminSecurityMessageHandler DelegatingHandler private r