在*某些* WebAPI 控制器上禁用 SSL 客户端证书?

2024-03-05

为未来的读者编辑:不幸的是,赏金奖励答案 不起作用;我现在对此无能为力。但请阅读我自己的答案 下面(通过测试)- 确认可以使用最少的代码更改

我们有一个完全采用 ASP.NET WebAPI 2.2 的 Azure 云服务 (WebRole)(无 MVC,前端是 Angular)。我们的一些控制器/REST端点通过SSL(客户端证书身份验证/相互身份验证)与第三方云服务通信,其余控制器/端点也通过SSL与HTML5/AngularJS前端通信(但更传统的服务器身份验证) SSL)。我们没有任何非 SSL 端点。我们通过云服务启动任务启用了客户端 SSL,例如:

IF NOT DEFINED APPCMD SET APPCMD=%SystemRoot%\system32\inetsrv\AppCmd.exe
%APPCMD% unlock config /section:system.webServer/security/access

问题:该设置是站点范围内的,因此即使用户点击第一页(例如https://domain.com https://domain.com,返回 angularJS 的 index.html)他们的浏览器要求他们提供客户端 SSL 证书。 (下图)

如果有办法

  1. 将客户端 SSL 证书请求限制为仅与第 3 方云服务通信的 WebAPI 控制器?

OR

  1. 为我们的前端驱动 webapi 控制器跳过客户端 SSL 身份验证?

我们服务器的 web.config 很复杂,但相关片段如下:

<system.webServer>
  <security>
    <access sslFlags="SslNegotiateCert" />
  </security>
</system.webServer>

And the screenshot of the client hitting a regular WebAPI endpoint yet attempting client SSL Authentication (happens in any browser, Chrome, Firefox or IE) enter image description here


不幸的是,克莱夫瑟里斯获得赏金的答案不起作用。它尝试在 HTTP 服务器管道/处理中工作得太晚以获取客户端证书,但是这个帖子 https://stackoverflow.com/questions/8719416/can-client-certificate-settings-be-configured-in-the-web-config给了我一些想法。

该解决方案基于web.config这需要对“目录”进行特殊处理(也适用于虚拟文件夹或 WebAPI 路由)。

这是所需的逻辑:

https://www.server.com/acmeapi/ https://www.server.com/acmeapi/** => 带有客户端证书的 SSL

https://www.server.com/ https://www.server.com/** => SSL

这是对应的配置

<configuration>
  ...
  <system.webServer>
    <!-- This is for the rest of the site -->
    <security>
      <access sslFlags="Ssl" />
    </security>
  </system.webServer>

  <!--This is for the 3rd party API endpoint-->
  <location path="acmeapi">
    <system.webServer>
      <security>
        <access sslFlags="SslNegotiateCert"/>
      </security>
    </system.webServer>
  </location>
...
</configuration>

奖励积分

上面将相应地设置 SSL 握手。现在,您仍然需要检查代码中的客户端 SSL 证书是否是您期望的证书。完成如下

控制器代码:

[RoutePrefix("acmeapi")]
[SslClientCertActionFilter] // <== key part!
public class AcmeProviderController : ApiController
{
    [HttpGet]
    [Route("{userId}")]
    public async Task<OutputDto> GetInfo(Guid userId)
    {
        // do work ...
    }
}

上面执行 SSL 客户端验证的实际属性如下。可用于装饰整个控制器或仅装饰特定方法。

public class SslClientCertActionFilterAttribute : ActionFilterAttribute
{
    public List<string> AllowedThumbprints = new List<string>()
    {
        // Replace with the thumbprints the 3rd party
        // server will be presenting. You can make checks
        // more elaborate but always have thumbprint checking ...
        "0011223344556677889900112233445566778899",
        "1122334455667788990011223344556677889900" 
    };

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var request = actionContext.Request;

        if (!AuthorizeRequest(request))
        {
            throw new HttpResponseException(HttpStatusCode.Forbidden);
        }
    }

    private bool AuthorizeRequest(HttpRequestMessage request)
    {
        if (request==null)
            throw new ArgumentNullException("request");

        var clientCertificate = request.GetClientCertificate();

        if (clientCertificate == null || AllowedThumbprints == null || AllowedThumbprints.Count < 1)
        {
            return false;
        }

        foreach (var thumbprint in AllowedThumbprints)
        {
            if (clientCertificate.Thumbprint != null && clientCertificate.Thumbprint.Equals(thumbprint, StringComparison.InvariantCultureIgnoreCase))
            {
                return true;
            }
        }
        return false;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在*某些* WebAPI 控制器上禁用 SSL 客户端证书? 的相关文章

  • 将处理后的图形绘制到另一个图形中

    我想将一个经过处理的图形绘制到另一个图形中 I have two graphics var gHead Graphics FromImage h var gBackground Graphics FromImage b Transform
  • Linux TUN/TAP:无法从 TAP 设备读回数据

    问题是关于如何正确配置想要使用 Tun Tap 模块的 Linux 主机 My Goal 利用现有的路由软件 以下为APP1和APP2 但拦截并修改其发送和接收的所有消息 由Mediator完成 我的场景 Ubuntu 10 04 Mach
  • Guid 应包含 32 位数字和 4 个破折号

    我有一个包含 createuserwizard 控件的网站 创建帐户后 验证电子邮件及其验证 URL 将发送到用户的电子邮件地址 但是 当我进行测试运行时 单击电子邮件中的 URL 时 会出现以下错误 Guid should contain
  • 调试内存不足异常

    在修复我制作的小型 ASP NET C Web 应用程序的错误时 我遇到了 OutOfMemoryException 没有关于在哪里查看的提示 因为这是一个编译时错误 如何诊断此异常 我假设这正是内存分析发挥作用的地方 有小费吗 Thank
  • C++11 函数局部静态 const 对象的线程安全初始化

    这个问题已在 C 98 上下文中提出 并在该上下文中得到回答 但没有明确说明有关 C 11 的内容 const some type create const thingy lock my lock some mutex static con
  • 为什么 std::allocator 在 C++17 中丢失成员类型/函数?

    一边看着std 分配器 http en cppreference com w cpp memory allocator 我看到成员 value type pointer const pointer reference const refer
  • Xamarin Android:获取内存中的所有进程

    有没有办法读取所有进程 而不仅仅是正在运行的进程 如果我对 Android 的理解正确的话 一次只有一个进程在运行 其他所有进程都被冻结 后台进程被忽略 您可以使用以下代码片段获取当前正在运行的所有 Android 应用程序进程 Activ
  • C++派生模板类继承自模板基类,无法调用基类构造函数[重复]

    这个问题在这里已经有答案了 我试图从基类 模板 继承 派生类也是模板 它们具有相同的类型 T 我收到编译错误 非法成员初始化 Base 不是基类或成员 为什么 如何调用基类构造函数 include
  • 两组点之间的最佳匹配

    I ve got two lists of points let s call them L1 P1 x1 y1 Pn xn yn and L2 P 1 x 1 y 1 P n x n y n 我的任务是找到它们点之间的最佳匹配 以最小化它
  • C# 创建数组的数组

    我正在尝试创建一个将使用重复数据的数组数组 如下所示 int list1 new int 4 1 2 3 4 int list2 new int 4 5 6 7 8 int list3 new int 4 1 3 2 1 int list4
  • 用于从字符串安全转换的辅助函数

    回到 VB6 我编写了一些函数 让我在编码时无需关心字符串的 null 和 数字的 null 和 0 等之间的区别 编码时 没有什么比添加特殊情况更能降低我的工作效率了用于处理可能导致一些不相关错误的数据的代码 9999 10000 如果我
  • “MyClass”的类型初始值设定项引发异常

    以下是我的Windows服务代码 当我调试代码时 我收到错误 异常 CSMessageUtility CSDetails 的类型初始值设定项引发异常 using System using System Collections Generic
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • Fluent NHibernate 日期时间 UTC

    我想创建一个流畅的 nhibernate 映射来通过以下方式映射 DateTime 字段 保存时 保存 UTC 值 读取时 调整为本地时区值 实现此映射的最佳方法是什么 就我个人而言 我会将日期存储在 UTC 格式的对象中 然后在读 写时在
  • 同时从多个流中捕获、最佳方法以及如何减少 CPU 使用率

    我目前正在编写一个应用程序 该应用程序将捕获大量 RTSP 流 在我的例子中为 12 个 并将其显示在 QT 小部件上 当我超过大约 6 7 个流时 问题就会出现 CPU 使用率激增并且出现明显的卡顿 我认为它不是 QT 绘制函数的原因是因
  • 热重载时调用方法

    我正在使用 Visual Studio 2022 和 C 制作游戏 我想知道当您热重新加载应用程序 当它正在运行时 时是否可以触发一些代码 我基本上有 2 个名为 UnloadLevel 和 LoadLevel 的方法 我想在热重载时执行它
  • Swagger 为 ASP.CORE 3 中的字典生成错误的 URL

    当从查询字符串中提取的模型将字典作为其属性之一时 Swagger 会生成不正确的 URL 如何告诉 Swagger 更改 URL 中字典的格式或手动定义输入参数模式而不自动生成 尝试使用 Swashbuckle 和 NSwag 控制器 pu
  • Azure函数版本2.0-应用程序blobTrigger不工作

    我有一个工作功能应用程序 它有一个 blob 输入和一个事件中心输出 在测试版中工作 随着最新的更改 我的功能不再起作用 我尝试根据发行说明更新 host json 文件 但它没有引用 blob 触发器 version 2 0 extens
  • 如何确定母版页中正在显示哪个子页?

    我正在母版页上编写代码 我需要知道正在显示哪个子 内容 页面 我怎样才能以编程方式做到这一点 我用这个 string pageName this ContentPlaceHolder1 Page GetType FullName 它以 AS

随机推荐