当前位置: 首页 > news >正文

未成功,做个记录,SelfHost.HttpSelfHostServer 如何加载证书

System.Web.Http.SelfHost.HttpSelfHostServer 如何加载证书 Dim certificate = LoadCertificateFromFile(certPath, certPassword)

在 System.Web.Http.SelfHost.HttpSelfHostServer 中加载证书需要通过 HttpSelfHostConfiguration 类进行配置。以下是完整的实现方案:

步骤 1:修改证书加载方法

保持之前的证书加载方法不变:

Imports System.Security.Cryptography.X509Certificates' 从本地文件路径加载证书
Private Shared Function LoadCertificateFromFile(certPath As String, certPassword As String) As X509Certificate2TryDim certificate = New X509Certificate2(certPath,certPassword,X509KeyStorageFlags.MachineKeySet OrX509KeyStorageFlags.PersistKeySet OrX509KeyStorageFlags.Exportable)Return certificateCatch ex As ExceptionThrow New Exception("加载证书失败: " & ex.Message, ex)End Try
End Function

步骤 2:配置 HttpSelfHostConfiguration 使用证书

在 Main 方法中,创建配置并指定证书:

Imports System
Imports System.Net
Imports System.Web.Http
Imports System.Web.Http.SelfHost
Imports System.Security.Cryptography.X509CertificatesModule ProgramSub Main()' 证书路径和密码Dim certPath As String = "C:\Path\To\YourCertificate.pfx"Dim certPassword As String = "YourSecurePassword"' 服务基地址(HTTPS)Dim baseAddress As New Uri("https://localhost:44300/")' 从文件加载证书Dim certificate = LoadCertificateFromFile(certPath, certPassword)' 创建配置并指定证书Dim config As New HttpSelfHostConfiguration(baseAddress)' 配置路由config.Routes.MapHttpRoute(name:="DefaultApi",routeTemplate:="api/{controller}/{id}",defaults:=New With {.id = RouteParameter.Optional})' 临时信任所有证书(仅用于开发环境)ServicePointManager.ServerCertificateValidationCallback = Function(sender, cert, chain, errors) True' 创建服务器并启动Using server As New HttpSelfHostServer(config)' 添加 HTTPS 端点并指定证书Dim binding = New HttpBindingInfo(HttpScheme.Https,certificate)server.Configuration.Services.Replace(GetType(IHttpBindingInfoProvider),New CustomBindingInfoProvider(binding))server.OpenAsync().Wait()Console.WriteLine("服务已启动: " & baseAddress)Console.WriteLine("按 Enter 停止服务...")Console.ReadLine()End UsingEnd Sub
End Module

步骤 3:创建自定义绑定信息提供程序

需要创建一个辅助类来提供证书绑定信息:

Imports System.Web.Http.SelfHost.ServiceModel
Imports System.ServiceModel.ChannelsPublic Class CustomBindingInfoProviderImplements IHttpBindingInfoProviderPrivate ReadOnly _bindingInfo As HttpBindingInfoPublic Sub New(bindingInfo As HttpBindingInfo)_bindingInfo = bindingInfoEnd SubPublic Function GetBindingInfo() As HttpBindingInfo Implements IHttpBindingInfoProvider.GetBindingInfoReturn _bindingInfoEnd Function
End Class

关键点说明

  1. 证书绑定方式

    • 通过 HttpBindingInfo 类指定 HTTPS 协议和证书
    • 使用 CustomBindingInfoProvider 替换默认的绑定信息提供程序
  2. 端口权限

    • 确保应用程序有访问指定端口的权限
    • 非管理员用户无法绑定 1-1023 之间的端口
  3. 安全注意事项

    • 生产环境必须使用受信任的证书
    • 禁用 ServicePointManager.ServerCertificateValidationCallback 的临时信任代码

完整代码示例

将上述代码组合在一起:

Imports System
Imports System.Net
Imports System.Web.Http
Imports System.Web.Http.SelfHost
Imports System.Security.Cryptography.X509Certificates
Imports System.Web.Http.SelfHost.ServiceModel
Imports System.ServiceModel.ChannelsModule ProgramSub Main()' 证书路径和密码Dim certPath As String = "C:\Path\To\YourCertificate.pfx"Dim certPassword As String = "YourSecurePassword"' 服务基地址(HTTPS)Dim baseAddress As New Uri("https://localhost:44300/")' 从文件加载证书Dim certificate = LoadCertificateFromFile(certPath, certPassword)' 创建配置并指定证书Dim config As New HttpSelfHostConfiguration(baseAddress)' 配置路由config.Routes.MapHttpRoute(name:="DefaultApi",routeTemplate:="api/{controller}/{id}",defaults:=New With {.id = RouteParameter.Optional})' 临时信任所有证书(仅用于开发环境)ServicePointManager.ServerCertificateValidationCallback = Function(sender, cert, chain, errors) True' 创建服务器并启动Using server As New HttpSelfHostServer(config)' 添加 HTTPS 端点并指定证书Dim binding = New HttpBindingInfo(HttpScheme.Https,certificate)server.Configuration.Services.Replace(GetType(IHttpBindingInfoProvider),New CustomBindingInfoProvider(binding))server.OpenAsync().Wait()Console.WriteLine("服务已启动: " & baseAddress)Console.WriteLine("按 Enter 停止服务...")Console.ReadLine()End UsingEnd Sub' 从本地文件路径加载证书Private Shared Function LoadCertificateFromFile(certPath As String, certPassword As String) As X509Certificate2TryDim certificate = New X509Certificate2(certPath,certPassword,X509KeyStorageFlags.MachineKeySet OrX509KeyStorageFlags.PersistKeySet OrX509KeyStorageFlags.Exportable)Return certificateCatch ex As ExceptionThrow New Exception("加载证书失败: " & ex.Message, ex)End TryEnd Function
End Module' 自定义绑定信息提供程序
Public Class CustomBindingInfoProviderImplements IHttpBindingInfoProviderPrivate ReadOnly _bindingInfo As HttpBindingInfoPublic Sub New(bindingInfo As HttpBindingInfo)_bindingInfo = bindingInfoEnd SubPublic Function GetBindingInfo() As HttpBindingInfo Implements IHttpBindingInfoProvider.GetBindingInfoReturn _bindingInfoEnd Function
End Class

常见问题

  1. 证书加载失败

    System.Security.Cryptography.CryptographicException: 无法访问私钥
    
     
    • 解决:确保证书文件存在且应用程序有读取权限,使用正确的密码。
  2. 端口被占用

    System.InvalidOperationException: 无法启动 HTTP 服务器,端口已被占用
    
     
    • 解决:使用 netstat -ano | findstr :44300 检查并关闭占用端口的进程。
  3. HTTPS 连接被拒绝

    • 解决:确认证书格式正确(PFX 且包含私钥),并通过 certificate.Verify() 验证证书有效性。

通过这种方式,您可以在 HttpSelfHostServer 中成功加载并使用证书,实现安全的 HTTPS 通信。

严重性 代码 说明 项目 文件 行 禁止显示状态 错误(活动) BC30002 未定义类型“HttpBindingInfo”。IHttpBindingInfoProvider,CustomBindingInfoProvider

您遇到的错误是因为 HttpBindingInfo 和 IHttpBindingInfoProvider 类型在较新版本的 .NET 中已被弃用或移动到不同的命名空间。以下是针对 ASP.NET Web API 2 的兼容解决方案:

替代方案:使用自定义 HTTP 消息处理程序

通过自定义消息处理程序来配置 HTTPS 证书,这种方法不依赖于已弃用的 HttpBindingInfo 类:

Imports System
Imports System.Net
Imports System.Net.Http
Imports System.Security.Cryptography.X509Certificates
Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports System.Web.Http
Imports System.Web.Http.SelfHostModule ProgramSub Main()' 证书路径和密码Dim certPath As String = "C:\Path\To\YourCertificate.pfx"Dim certPassword As String = "YourSecurePassword"' 服务基地址(HTTPS)Dim baseAddress As New Uri("https://localhost:44300/")' 从文件加载证书Dim certificate = LoadCertificateFromFile(certPath, certPassword)' 创建配置Dim config As New HttpSelfHostConfiguration(baseAddress)' 配置路由config.Routes.MapHttpRoute(name:="DefaultApi",routeTemplate:="api/{controller}/{id}",defaults:=New With {.id = RouteParameter.Optional})' 临时信任所有证书(仅用于开发环境)ServicePointManager.ServerCertificateValidationCallback = Function(sender, cert, chain, errors) True' 配置 HTTPS 端点config.HostNameComparisonMode = HostNameComparisonMode.Exactconfig.MaxReceivedMessageSize = 2147483647 ' 增大消息大小限制' 创建服务器并启动Using server As New HttpSelfHostServer(config)' 启动服务器前绑定证书(通过自定义配置)BindHttpsCertificate(baseAddress.Port, certificate)server.OpenAsync().Wait()Console.WriteLine("服务已启动: " & baseAddress)Console.WriteLine("按 Enter 停止服务...")Console.ReadLine()End UsingEnd Sub' 从本地文件路径加载证书Private Shared Function LoadCertificateFromFile(certPath As String, certPassword As String) As X509Certificate2TryDim certificate = New X509Certificate2(certPath,certPassword,X509KeyStorageFlags.MachineKeySet OrX509KeyStorageFlags.PersistKeySet OrX509KeyStorageFlags.Exportable)Return certificateCatch ex As ExceptionThrow New Exception("加载证书失败: " & ex.Message, ex)End TryEnd Function' 绑定证书到指定端口(使用 netsh 命令)Private Shared Sub BindHttpsCertificate(port As Integer, certificate As X509Certificate2)' 获取证书指纹Dim thumbprint = certificate.Thumbprint' 创建 SSL 证书绑定(使用 Process 调用 netsh)Dim process As New System.Diagnostics.Process()process.StartInfo.FileName = "netsh"process.StartInfo.Arguments = String.Format("http add sslcert ipport=0.0.0.0:{0} certhash={1} appid=""{{{2}}}""",port,thumbprint,Guid.NewGuid().ToString())process.StartInfo.UseShellExecute = Falseprocess.StartInfo.RedirectStandardOutput = Trueprocess.StartInfo.RedirectStandardError = Trueprocess.Start()' 等待命令执行完成process.WaitForExit()' 检查是否有错误If process.ExitCode <> 0 ThenDim errorOutput = process.StandardError.ReadToEnd()Throw New Exception("绑定证书失败: " & errorOutput)End IfEnd Sub
End Module

关键点说明

  1. 证书绑定方式

    • 通过 netsh http add sslcert 命令将证书绑定到指定端口
    • 使用 BindHttpsCertificate 方法执行此操作
  2. 权限要求

    • 需要管理员权限才能执行 netsh 命令
    • 建议以管理员身份运行应用程序
  3. 清理绑定

    • 应用程序停止时,证书绑定不会自动解除
    • 可使用 netsh http delete sslcert ipport=0.0.0.0:44300 手动删除绑定

完整解决方案

如果上述方法仍有问题,可以尝试使用 OWIN 自托管 替代(更现代的方案):

vb

Imports Microsoft.Owin.Hosting
Imports Owin
Imports System.Web.Http
Imports System.Security.Cryptography.X509CertificatesPublic Class StartupPublic Sub Configuration(app As IAppBuilder)Dim config As New HttpConfiguration()config.Routes.MapHttpRoute(name:="DefaultApi",routeTemplate:="api/{controller}/{id}",defaults:=New With {.id = RouteParameter.Optional})app.UseWebApi(config)End Sub
End ClassModule ProgramSub Main()Dim certPath As String = "C:\Path\To\YourCertificate.pfx"Dim certPassword As String = "YourSecurePassword"Dim baseAddress As String = "https://localhost:44300/"Dim certificate = LoadCertificateFromFile(certPath, certPassword)' 临时信任所有证书(仅用于开发环境)System.Net.ServicePointManager.ServerCertificateValidationCallback = Function(sender, cert, chain, errors) True' 启动 OWIN 自托管服务Dim options As New StartOptions(baseAddress)options.Settings.Add("sslCertThumbprint", certificate.Thumbprint)Using webApp = WebApp.Start(Of Startup)(options)Console.WriteLine("服务已启动: " & baseAddress)Console.WriteLine("按 Enter 停止服务...")Console.ReadLine()End UsingEnd SubPrivate Shared Function LoadCertificateFromFile(certPath As String, certPassword As String) As X509Certificate2' 与前面的方法相同...End Function
End Module

选择建议

  1. 传统 Web API 自托管:使用第一个方案(通过 netsh 绑定证书)
  2. 现代 OWIN 自托管:使用第二个方案(更简单且兼容性更好)

无论选择哪种方案,都需要确保:

  • 证书格式正确(PFX 且包含私钥)
  • 应用程序有访问证书的权限
  • 端口未被其他应用占用

certhash={1} appid=""{{{2}}}""", 这2个参数什么意思

netsh http add sslcert命令中,certhashappid是两个关键参数,它们的作用和含义如下:

1. certhash参数(证书哈希值)

  • 含义:指定要绑定到 HTTP 端口的 SSL 证书的指纹(Thumbprint),即证书的唯一标识符。
  • 作用
    • 操作系统通过指纹定位到注册表中存储的具体证书。
    • 确保绑定的是正确的证书,避免与其他证书混淆。
  • 获取方式
    • 通过X509Certificate2.Thumbprint属性获取(如代码中的certificate.Thumbprint)。
    • 也可通过 Windows 证书管理器查看(运行certmgr.msc,找到证书后查看 “详细信息” 中的 “指纹”)。

2. appid参数(应用程序 ID)

  • 含义:指定绑定证书的应用程序的唯一标识符(GUID)
  • 作用
    • 区分不同应用程序对同一端口的绑定(理论上一个端口只能绑定一个证书)。
    • 当多个应用程序需要共享端口时,通过appid标识各自的证书绑定。
  • 格式要求
    • 必须是符合 GUID 格式的字符串(例如{12345678-ABCD-EFGH-IJKL-1234567890AB})。
    • 代码中使用Guid.NewGuid().ToString()动态生成唯一 ID,避免冲突。

命令参数示例解析

vb

netsh http add sslcert ipport=0.0.0.0:44300 certhash={1} appid="{{{2}}}"

  • ipport=0.0.0.0:44300:绑定到所有 IP 地址的 44300 端口。
  • certhash={1}:替换为实际证书的指纹(例如A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6Q7R8)。
  • appid="{{{2}}}":替换为生成的 GUID(例如{12345678-1234-1234-1234-123456789012})。

注意事项

  1. 权限要求
    • 必须以管理员权限运行netsh命令,否则会提示 “访问被拒绝”。
  2. 证书匹配
    • certhash必须与证书存储中的指纹完全一致(区分大小写,且不带空格)。
  3. 端口冲突
    • 一个端口只能绑定一个证书,若端口已被其他应用绑定,需先删除原有绑定:

      bash

      netsh http delete sslcert ipport=0.0.0.0:44300
      
  4. appid的作用范围
    • 若多个应用程序使用相同appid,它们可以共享同一个端口的证书绑定(但需谨慎使用)。
http://www.dtcms.com/a/267587.html

相关文章:

  • 【Prometheus】Grafana、Alertmanager集成
  • 小架构step系列05:Springboot三种运行模式
  • 理想汽车6月交付36279辆 第二季度共交付111074辆
  • 基于微信小程序的校园跑腿系统
  • MySQL——9、事务管理
  • Java-继承
  • 远程协助软件:Git的用法
  • STM32第15天串口中断接收
  • 数据结构:数组抽象数据类型(Array ADT)
  • oracle的内存架构学习
  • Hashcat 最快密码恢复工具实践指南
  • jvm架构原理剖析篇
  • C++ Qt 基础教程:信号与槽机制详解及 QPushButton 实战
  • virtualbox+vagrant私有网络宿主机无法ping通虚拟机问题请教
  • Apache 配置文件提权的实战思考
  • 数据库-元数据表
  • docker容器中Mysql数据库的备份与恢复
  • Java的AI新纪元:Embabel如何引领智能应用开发浪潮
  • 一文讲清楚React中setState的使用方法和机制
  • 应用标签思路参考
  • wsl查看磁盘文件并清理空间
  • Django跨域
  • 什么是单点登录SSO?有哪些常用的实现方式?
  • Android PNG/JPG图ARGB_8888/RGB_565‌解码形成Bitmap在物理内存占用大小的简单计算
  • SpringBoot系列—入门
  • ffplay6 播放器关键技术点分析 1/2
  • NumPy-核心函数np.matmul()深入解析
  • UI前端与数字孪生融合:为智能制造提供可视化生产调度方案
  • 分享一些服务端请求伪造SSRF的笔记
  • RAL-2025 | 触觉助力无人机空中探索!基于柔顺机器人手指的无人机触觉导航