ASP.NET Core (3.1) 在自托管 (Kestrel) 应用程序中重新使用 IIS 证书

发布于 2025-01-12 07:30:08 字数 2066 浏览 1 评论 0原文

我有一个 ASP.NET Core (3.1) 应用程序,它是自托管的并作为服务运行。我想为其公开一个 HTTPS 端点。在同一台计算机上安装了一个 IIS,其中已配置了 https 和证书: 输入图片此处的描述

证书似乎存储在本地计算机证书存储中: 证书管理器

我还可以通过 powershell 列出它:

> get-childitem cert:\LocalMachine\My\ | format-table NotAfter, Subject

NotAfter            Subject
--------            -------
27.10.2023 07:38:45 <irrelevant>
08.03.2022 09:52:44 CN=a7642e58-2cdf-4e9b-a277-60fad84d7c64, DC=3336d6b0-b132-47ee-a49b-3ab470a5336e
23.02.2022 21:51:53 CN=a7642e58-2cdf-4e9b-a277-60fad84d7c64, DC=3336d6b0-b132-47ee-a49b-3ab470a5336e
27.10.2031 06:48:06 CN=a7642e58-2cdf-4e9b-a277-60fad84d7c64
26.10.2024 10:41:03 E=****.com, CN=****, OU=IT, O=****, L=****, S=***, C=**

我更改了 appsettings.json 以使用商店中的证书:

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Kestrel": {
    "EndPoints": {
      "Http": {
        "Url": "http://*:5000"
      },
      "HttpsDefaultCert": {
        "Url": "https://*:5001"
      }
    },
    "Certificates": {
      "Default": {
        "Subject": "E=****.com, CN=****, OU=IT, O=****, L=****, S=***, C=**",
        "Store": "My",
        "Location": "LocalMachine",
        "AllowInvalid": "true"
      }
    }
  }
}

但这似乎不起作用。我总是收到以下错误:

 System.InvalidOperationException: The requested certificate E=****.com, CN=****, OU=IT, O=****, L=****, S=***, C=** could not be found in LocalMachine/My with AllowInvalid setting: True

我不知道可能是什么问题。 我认为唯一可能有问题的是证书主题实际上包含主题中的换行符:
证书

我不知道这是否是问题所在,并且我不知道如何在 appsettings.json 中输入它,因为无法输入多行值。

I have an ASP.NET Core (3.1) application which is self-hosted and running as a service. I would like to expose an HTTPS endpoint for it. On the same machine there is an IIS instaled with already configured https together with certificate:
enter image description here

The certificate seems to stored in local computer certificate store:
Certificate manager

I can also list it via the powershell:

> get-childitem cert:\LocalMachine\My\ | format-table NotAfter, Subject

NotAfter            Subject
--------            -------
27.10.2023 07:38:45 <irrelevant>
08.03.2022 09:52:44 CN=a7642e58-2cdf-4e9b-a277-60fad84d7c64, DC=3336d6b0-b132-47ee-a49b-3ab470a5336e
23.02.2022 21:51:53 CN=a7642e58-2cdf-4e9b-a277-60fad84d7c64, DC=3336d6b0-b132-47ee-a49b-3ab470a5336e
27.10.2031 06:48:06 CN=a7642e58-2cdf-4e9b-a277-60fad84d7c64
26.10.2024 10:41:03 E=****.com, CN=****, OU=IT, O=****, L=****, S=***, C=**

I changed the appsettings.json to use the certificate from the store:

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Kestrel": {
    "EndPoints": {
      "Http": {
        "Url": "http://*:5000"
      },
      "HttpsDefaultCert": {
        "Url": "https://*:5001"
      }
    },
    "Certificates": {
      "Default": {
        "Subject": "E=****.com, CN=****, OU=IT, O=****, L=****, S=***, C=**",
        "Store": "My",
        "Location": "LocalMachine",
        "AllowInvalid": "true"
      }
    }
  }
}

However this does not seem to work. I always get the following error:

 System.InvalidOperationException: The requested certificate E=****.com, CN=****, OU=IT, O=****, L=****, S=***, C=** could not be found in LocalMachine/My with AllowInvalid setting: True

I do not know what could be the problem. The only thing that I think might be problematic is that the certificate subject actually contains newlines in the subject:
Certificate

I do not know if this is the problem and I do not know how to enter it in the appsettings.json as multiline values can not be entered.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

两人的回忆 2025-01-19 07:30:09

我已经设法找到了这个问题。 Kestrel 在搜索证书时使用 FindBySubjectName

FindBySubjectName 执行子字符串搜索,并且不匹配证书的完整主题。如果您的证书主题类似于 'CN=my-certificate',则搜索 'CN=my-certificate' 将找不到任何内容。仅搜索 'my-certificate' 即可。

附加说明:除了指定正确的搜索表达式之外,请确保运行应用程序的帐户具有足够的权限来从证书存储中读取证书。证书确实具有 ACL,因此您不必以管理员身份运行应用程序。

I've managed to track down the issue. Kestrel uses FindBySubjectName when searching for certificate.

FindBySubjectName does a sub-string search and will not match the full Subject of the certificate. If your certificate subject is something like 'CN=my-certificate' then searching for 'CN=my-certificate' will not find anything. Searching only for 'my-certificate' will work.

Additional note: In addition to specifying the correct search expression, make sure that the account under which you are running the application has sufficient permissions to read the certificate from certificate store. Certificates do have ACL so you do not have to run your app as an administrator.

旧故 2025-01-19 07:30:09

我参考了为 Kestrel 上运行的 Asp.NetCore 应用程序配置 SSL 证书的文档。

我注意到一些 URL 和端口设置也存储在 Properties/LaunchSettings.json 文件中。

请参阅此处:配置端点ASP.NET Core Kestrel Web 服务器

此外,我注意到您已将证书放在默认值下。我找到了其他配置证书的方法。你可以尝试测试它们。

在以下 appsettings.json 示例中:

  • AllowInvalid 设置为 true 以允许使用无效证书(例如自签名证书)。
  • 任何未指定证书(以下示例中的 HttpsDefaultCert)的 HTTPS 端点都会回退到“Certificates:Default”下定义的证书或开发证书。
{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertAndKeyFile": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Path": "<path to .pem/.crt file>",
          "KeyPath": "<path to .key file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5003",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5004"
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

架构注释:

  • 端点名称不区分大小写。例如,HTTPS 和 Https 是等效的。
  • 每个端点都需要 Url 参数。此参数的格式与顶级 URL 配置参数相同,只是它仅限于单个值。
  • 这些端点会替换顶级 URL 配置中定义的端点,而不是添加到其中。通过 Listen 在代码中定义的端点与配置部分中定义的端点是累积的。
  • 证书部分是可选的。如果未指定“证书”部分,则使用“证书:默认值”中定义的默认值。如果没有可用的默认值,则使用开发证书。如果没有默认值并且开发证书不存在,服务器将引发异常并无法启动。
  • 证书部分支持多个证书源。
  • 可以在配置中定义任意数量的端点,只要它们不会导致端口冲突。

参考:替换配置中的默认证书

I refer to the documentation for configuring the SSL certificates for Asp.NetCore app running on Kestrel.

I noticed some URL and ports settings also get stored in Properties/LaunchSettings.json file.

See Here: Configure endpoints for the ASP.NET Core Kestrel web server

Further, I noticed that you have put the Certificate under Defaults. I found other ways to configure the certificate. You could try to test them.

In the following appsettings.json example:

  • Set AllowInvalid to true to permit the use of invalid certificates (for example, self-signed certificates).
  • Any HTTPS endpoint that doesn't specify a certificate (HttpsDefaultCert in the example that follows) falls back to the cert defined under Certificates:Default or the development certificate.

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertAndKeyFile": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Path": "<path to .pem/.crt file>",
          "KeyPath": "<path to .key file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5003",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5004"
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

Schema notes:

  • Endpoints names are case-insensitive. For example, HTTPS and Https are equivalent.
  • The Url parameter is required for each endpoint. The format for this parameter is the same as the top-level Urls configuration parameter except that it's limited to a single value.
  • These endpoints replace those defined in the top-level Urls configuration rather than adding to them. Endpoints defined in code via Listen are cumulative with the endpoints defined in the configuration section.
  • The Certificate section is optional. If the Certificate section isn't specified, the defaults defined in Certificates:Default are used. If no defaults are available, the development certificate is used. If there are no defaults and the development certificate isn't present, the server throws an exception and fails to start.
  • The Certificate section supports multiple certificate sources.
  • Any number of endpoints may be defined in Configuration as long as they don't cause port conflicts.

Reference: Replace the default certificate from configuration

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文