为IdentityServer4添加签名凭据

26
我们正在使用.NET Core Web应用程序("http://docs.identityserver.io/en/release/quickstarts/0_overview.html")中的IdentityServer4。 我们已经将AddDeveloperSigningCredential替换为AddSigningCredential(CreateSigningCredential())。由于在生产环境中不能使用AddDeveloperSigningCredential,因为需要用一些持久的密钥材料来替换它。我们对IdentityServer4还不太了解,我们的问题是,以下方式是否适用于在生产环境中创建签名凭证?还是我们需要在此进行一些更改?
这是我们的startup.cs文件:
public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IConfiguration>(Configuration);

    //connection string
    string connectionString = Configuration.GetConnectionString("IdentityServer");

    var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;

    services.AddIdentityServer().AddDeveloperSigningCredential
    .AddSigningCredential(CreateSigningCredential())
    // this adds the config data from DB (clients, resources)
    .AddConfigurationStore(options =>
    {
        options.ConfigureDbContext = builder =>
        builder.UseSqlServer(connectionString,
            sql => sql.MigrationsAssembly(migrationsAssembly));
                }) // this adds the operational data from DB (codes, tokens, consents)
    .AddOperationalStore(options =>
    {
        options.ConfigureDbContext = builder =>
        builder.UseSqlServer(connectionString,
            sql => sql.MigrationsAssembly(migrationsAssembly));

        // this enables automatic token cleanup. this is optional.
        options.EnableTokenCleanup = true;
        options.TokenCleanupInterval = 30;
        });
}

private SigningCredentials CreateSigningCredential()
{
    var credentials = new SigningCredentials(GetSecurityKey(), SecurityAlgorithms.RsaSha256Signature);

    return credentials;
}
private RSACryptoServiceProvider GetRSACryptoServiceProvider()
{
    return new RSACryptoServiceProvider(2048);
}
private SecurityKey GetSecurityKey()
{
    return new RsaSecurityKey(GetRSACryptoServiceProvider());
}

您当前是否正在使用 Azure 或 AWS 的 PaaS 服务? - aaronR
3个回答

11

这里有一个Gist,可帮助使用asp.net core 2.x的Ids4。

它包含一个RsaKeyService类,可以像下面一样注入到服务提供程序中:

var rsa = new RsaKeyService(Environment, TimeSpan.FromDays(30));
services.AddTransient<RsaKeyService>(provider => rsa);

这确保RSA密钥最多仅在30天内使用,然后重新生成一个新的密钥。

要使用密钥,您可以调用rsa.GetKey(),要注册签名凭证,请使用:

builder.AddSigningCredential(rsa.GetKey());

9

以下是使用X509自签名证书的简单方法。

在IdentityServer4中,使用自签名证书进行令牌签名的一种方法是将证书存储在应用程序的“wwwroot”文件夹下。

public void ConfigureServices(IServiceCollection services)
{
        .....other code .....

        var fileName = Path.Combine(env.WebRootPath, "YOUR_FileName" );            

        if (!File.Exists(fileName))
        {
            throw new FileNotFoundException("Signing Certificate is missing!");
        }

        var cert = new X509Certificate2(fileName, "Your_PassPhrase" );

        services.AddIdentityServer().AddSigningCredential(cert)

        ...other code.....
}

1
你能解释一下“口令短语”在其中扮演的角色吗? - Anton Toshik
14
不要将私有证书文件放在WebRootPath中,这会使您的私钥对整个互联网可读。 - Fred
8
如果使用StaticFiles中间件,我认为WebRootPath始终以默认配置提供。我认为应该使用ContentRootPath而不是WebRootPath - Fred
3
抱歉,@Fred,你说得完全正确!我正在使用ContentRootPath,但因为咖啡因过度兴奋而没有注意到区别。 - Astravagrant
1
@Junaid 不适用于生产。 - aaronR
显示剩余4条评论

2
我在这里没有看到任何持久性的加载,所以我不得不说不适合。我提供了一个加载证书的示例:如何在AWS无服务器Lambda环境中替换AddDeveloperSigningCredential? 我建议按照那个方法进行操作。您可以将证书部署在操作系统证书存储中,作为文件或作为应用程序本身的嵌入式资源。 预计:由于您已经表示X509证书不可行(很想知道原因),因此您需要自己向RsaSecurityKey提供RSAParameters。请参见Microsoft.IdentityModel.Tokens库中使用的测试数据: https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/d771b5c3ef22b7ff065e8fad1a63d6a2937b7d7f/test/Microsoft.IdentityModel.Tests/KeyingMaterial.cs 例如:
RsaParameters_2048 = new RSAParameters
{
        D = Base64UrlEncoder.DecodeBytes("C6EGZYf9U6RI5Z0BBoSlwy_gKumVqRx-dBMuAfPM6KVbwIUuSJKT3ExeL5P0Ky1b4p-j2S3u7Afnvrrj4HgVLnC1ks6rEOc2ne5DYQq8szST9FMutyulcsNUKLOM5cVromALPz3PAqE2OCLChTiQZ5XZ0AiH-KcG-3hKMa-g1MVnGW-SSmm27XQwRtUtFQFfxDuL0E0fyA9O9ZFBV5201ledBaLdDcPBF8cHC53Gm5G6FRX3QVpoewm3yGk28Wze_YvNl8U3hvbxei2Koc_b9wMbFxvHseLQrxvFg_2byE2em8FrxJstxgN7qhMsYcAyw1qGJY-cYX-Ab_1bBCpdcQ"),
        DP = Base64UrlEncoder.DecodeBytes("ErP3OpudePAY3uGFSoF16Sde69PnOra62jDEZGnPx_v3nPNpA5sr-tNc8bQP074yQl5kzSFRjRlstyW0TpBVMP0ocbD8RsN4EKsgJ1jvaSIEoP87OxduGkim49wFA0Qxf_NyrcYUnz6XSidY3lC_pF4JDJXg5bP_x0MUkQCTtQE"),
        DQ = Base64UrlEncoder.DecodeBytes("YbBsthPt15Pshb8rN8omyfy9D7-m4AGcKzqPERWuX8bORNyhQ5M8JtdXcu8UmTez0j188cNMJgkiN07nYLIzNT3Wg822nhtJaoKVwZWnS2ipoFlgrBgmQiKcGU43lfB5e3qVVYUebYY0zRGBM1Fzetd6Yertl5Ae2g2CakQAcPs"),
        Exponent = Base64UrlEncoder.DecodeBytes("AQAB"),
        InverseQ = Base64UrlEncoder.DecodeBytes("lbljWyVY-DD_Zuii2ifAz0jrHTMvN-YS9l_zyYyA_Scnalw23fQf5WIcZibxJJll5H0kNTIk8SCxyPzNShKGKjgpyZHsJBKgL3iAgmnwk6k8zrb_lqa0sd1QWSB-Rqiw7AqVqvNUdnIqhm-v3R8tYrxzAqkUsGcFbQYj4M5_F_4"),
        Modulus = Base64UrlEncoder.DecodeBytes("6-FrFkt_TByQ_L5d7or-9PVAowpswxUe3dJeYFTY0Lgq7zKI5OQ5RnSrI0T9yrfnRzE9oOdd4zmVj9txVLI-yySvinAu3yQDQou2Ga42ML_-K4Jrd5clMUPRGMbXdV5Rl9zzB0s2JoZJedua5dwoQw0GkS5Z8YAXBEzULrup06fnB5n6x5r2y1C_8Ebp5cyE4Bjs7W68rUlyIlx1lzYvakxSnhUxSsjx7u_mIdywyGfgiT3tw0FsWvki_KYurAPR1BSMXhCzzZTkMWKE8IaLkhauw5MdxojxyBVuNY-J_elq-HgJ_dZK6g7vMNvXz2_vT-SykIkzwiD9eSI9UWfsjw"),
        P = Base64UrlEncoder.DecodeBytes("_avCCyuo7hHlqu9Ec6R47ub_Ul_zNiS-xvkkuYwW-4lNnI66A5zMm_BOQVMnaCkBua1OmOgx7e63-jHFvG5lyrhyYEmkA2CS3kMCrI-dx0fvNMLEXInPxd4np_7GUd1_XzPZEkPxBhqf09kqryHMj_uf7UtPcrJNvFY-GNrzlJk"),
        Q = Base64UrlEncoder.DecodeBytes("7gvYRkpqM-SC883KImmy66eLiUrGE6G6_7Y8BS9oD4HhXcZ4rW6JJKuBzm7FlnsVhVGro9M-QQ_GSLaDoxOPQfHQq62ERt-y_lCzSsMeWHbqOMci_pbtvJknpMv4ifsQXKJ4Lnk_AlGr-5r5JR5rUHgPFzCk9dJt69ff3QhzG2c"),
};

嗨@mackie,实际上现在我们不打算使用X509证书,所以我们需要在X509证书的位置上使用其他东西。 - Rakesh Kumar
请问您能否提供一个示例,说明我们如何使用签名凭据而不是X509证书? - Rakesh Kumar
我已编辑了我的回答。为什么不使用自动生成的X509证书呢? - mackie
现在我们不打算使用X509证书 - 为什么? - Scott Brady
实际上,当我们在 AWS 环境中将身份服务器部署为无服务器 Lambda 时,面临一些问题。因此,我们将核心计划从 x509 更改为签名证书。 - Rakesh Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接