处理 Identity Server 客户端凭据流时发出自签名客户端证书

Issue in Self Signed Client Certificate while processing an Identity Server Client Credentials Flow

我使用 MakeCert.exe

为我的内部开发目的创建了一个自签名证书

步骤#1: 我使用以下命令创建了根 CA

makecert -n "CN=Bala root signing authority" -cy authority -r -sv root.pvk root.cer

步骤#2: 使用以下命令安装在步骤 #1 中创建的根 CA 证书

certutil -user -addstore Root root.cer

步骤#3: 我使用以下命令创建了客户端证书

makecert -pe -n "CN=Bala Client" -a sha1 -cy end ^ -sky signature ^ -ic root.cer -iv root1.pvk ^ -sv Bala.pvk Bala.cer

步骤 #4: 我使用以下命令为相应的客户端证书创建了一个 .pfx 文件

pvk2pfx -pvk Bala.pvk -spc Bala.cer -pfx Bala.pfx

根 CA 即 "CN=Bala root signing authority" 具有所有预期用途,并且安装在 Trusted Root Certification Authorities

根 CA 证书快照:"CN=Bala root signing authority"

客户端证书快照:"CN=Bala Client"

客户端证书有指纹:"83021C2C20096FFD8415A353E471FF1BD39ECA4E"

请看截图:

我的 IdentityServer3 中有一个客户端,我使用了相同的指纹 "83021C2C20096FFD8415A353E471FF1BD39ECA4E"

new Client
{
    ClientName = "Client Credentials Flow Client With Certificate",
    Enabled = true,
    ClientId = "cc.WithCertificate",
    Flow = Flows.ClientCredentials,

    ClientSecrets = new List<Secret>
        {
            new Secret
            {
                Value = "83021C2C20096FFD8415A353E471FF1BD39ECA4E",
                Type = Constants.SecretTypes.X509CertificateThumbprint,
                Description = "Client Certificate"
            },
        },

    AllowedScopes = new List<string>
        {
            "read"
        }
}

客户端控制台应用程序代码是

var cert = new X509Certificate2(@"Bala.pfx");
var handler = new WebRequestHandler();
handler.ClientCertificates.Add(cert);

string tokenEndPoint = ConfigurationManager.AppSettings["TokenEndpoint"];

var client = new TokenClient(
    tokenEndPoint,
    "cc.WithCertificate",
    handler);

// Calling the Token Service
var response = client.RequestClientCredentialsAsync("read").Result;

响应对象的快照:

执行代码后,我会收到错误状态代码的响应:response.Error ="Forbidden"

我遵循了我上一个问题中所说的所有按要求设置

请帮助我如何使用 Self Signed Certificate 验证应用程序。

经过长时间的努力,我找到了这个问题的解决方案(自签名证书)。有一种方法可以在身份服务器中使用自签名证书来基于客户端证书对用户进行身份验证。

在身份服务器中,我们使用证书生成令牌(默认情况下我们使用 idsrv3test.pfx),在客户端应用程序中我们使用证书 Client.pfx(默认情况下)。我研究了这背后的逻辑,我发现这两个证书的解决方案有一个共同的颁发者“DevRoot”。仅当 DevRoot 在受信任的根证书颁发机构中时,身份服务器 return 基于客户端证书的令牌,否则 IIS 不应允许请求并 return 返回状态码 403 禁止.

场景 #1:

场景 #2:

我遵循相同的逻辑,创建了根 CA 证书。此外,我创建了服务器和客户端证书,并将这些证书与根 CA 证书(即父证书)映射。证书应具有以下用途

  • 根 CA 证书 => 通用或服务器身份验证和客户端身份验证的组合
  • 服务器证书 => 仅服务器身份验证目的
  • 客户端证书 => 只有客户端

Note: For more information about Intended Purpose, refer http://www.alvestrand.no/objectid/1.3.6.1.5.5.7.3.html

服务器和客户端证书应为 .pfx 文件格式。让我们看看如何创建上述证书

确保先决条件工具在执行以下命令之前存在于您的系统中

步骤:#1

我们需要创建 CA、服务和客户端的证书以及私钥

证书颁发机构

makecert -r -pe -n "CN=Token Root CA" 
-sr LocalMachine -a sha1 -sky signature -cy authority -sv 
"D:\Certificate\IDRootCA.pvk" "D:\Certificate\IDRootCA.cer"

服务器证书

makecert -pe -n "CN=Server - Token Identity" -a sha1 -sky exchange 
-eku 1.3.6.1.5.5.7.3.1 -ic "D:\Certificate\IDRootCA.cer" -iv 
"D:\Certificate\IDRootCA.pvk" -sv "D:\Certificate\IDServer.pvk" "D:\Certificate\IDServer.cer"

客户端证书

makecert -pe -n "CN=Client - Token Identity" -a sha1 -sky exchange 
-eku 1.3.6.1.5.5.7.3.2 -ic "D:\Certificate\IDRootCA.cer" -iv 
"D:\Certificate\IDRootCA.pvk" -sv "D:\Certificate\IDClient.pvk" "D:\Certificate\IDClient.cer"

步骤:#2

我们需要导出 PFX 的服务文件和客户端证书

服务证书(PFX 格式)

pvk2pfx -pvk "D:\Certificate\IDServer.pvk" -spc "D:\Certificate\IDServer.cer" 
-pfx "D:\Certificate\IDServer.pfx"

客户端证书(PFX 格式)

pvk2pfx -pvk "D:\Certificate\IDClient.pvk" -spc "D:\Certificate\IDClient.cer" 
-pfx "D:\Certificate\IDClient.pfx"

步骤:#3

我们需要将 CA 导入受信任的根证书颁发机构证书存储

导入证书颁发机构 "CN=Token Root CA"

certutil -user -addstore Root "D:\Certificate\IDRootCA.cer"

Note: Here I import the Certificate only for the current user "-user". For more details refer http://certificate.fyicenter.com/685_Microsoft_CertUtil_Microsoft_certutil_-user_Certificate_St.html

在管理员模式下使用命令提示符执行上述所有命令,并将路径导航到“C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin”。上述路径应包含MakeCert.exe文件(确保一次)

上述命令将创建身份服务器所需的所有证书

身份服务器项目: 请使用服务器证书 "IDServer.pfx" 而不是 "idsrv3test.pfx" 并在 Certificates.cs 和 Web.config.

Note: The Private key is not required for this Self signed Certificate.

最后客户端控制台应用程序代码是

var cert = new X509Certificate2(@"IDClient.pfx");
var handler = new WebRequestHandler();
handler.ClientCertificates.Add(cert);

string tokenEndPoint = ConfigurationManager.AppSettings["TokenEndpoint"];

var client = new TokenClient(
    tokenEndPoint,
    "cc.WithCertificate",
    handler);

// Calling the Token Service
var response = client.RequestClientCredentialsAsync("read").Result;

终于成功拿到Access Token了