创建IDataProtectionProvider asp.net核心实例

时间:2018-08-25 17:51:38

标签: c# asp.net-mvc asp.net-core

我正在尝试创建一个静态类和方法来加密和解密asp.net核心中的数据。

但是问题是我必须在带有DI的构造函数中获取“ IDataProtectionProvider提供程序”,然后将其传递给方法,以便使用CreateProtector。

我不想要那样,而是直接想通过自己的方法实例化IDataProtectionProvider提供程序。

控制器代码:

private readonly IDataProtectionProvider _provider;
public addMDL(IDataProtectionProvider provider)
{
    _provider = provider;
}

public IActionResult OnGet()
{
    DataProProvider.decData(0, "ABC", _provider)
}

,静态类是:

public static class DataProProvider
{

    public static string encData(int intData, string strData, IDataProtectionProvider provider)
    {
        string str;
        IDataProtector dataProtector;
        dataProtector = provider.CreateProtector("AA");
        if (!string.IsNullOrEmpty(strData))
        {
            str = dataProtector.Protect(strData);
        }
        else
        {
            str = dataProtector.Protect(intData.ToString());
        }
        return str;
    }

    public static string decData(int intData, string strData, IDataProtectionProvider provider)
    {
        string str;
        IDataProtector dataProtector;
        dataProtector = provider.CreateProtector("A3");
        if (!string.IsNullOrEmpty(strData))
        {
            str = dataProtector.Unprotect(strData);
        }
        else
        {
            str = dataProtector.Unprotect(intData.ToString());
        }
        return str;
    }
}

[更新]

根据建议,我已使用Encrypting & Decrypting a String in C# enter link description here

3 个答案:

答案 0 :(得分:2)

浏览源代码,似乎只有通过一些反射黑客或代码复制才能实现不带DI的 IDataProtectionProvider 实例化。

看看this code,您可以看到在DI容器中为各种接口注册了哪些实现。例如。 IDataProtectionProvider 的实现是 KeyRingBasedDataProtectionProvider 。现在查看source of that class。它是内部的,因此您不能在声明程序集之外实例化它(无反射)。经过进一步的挖掘,事实证明提供程序也创建了KeyRingBasedDataProtector实例,这些实例也声明为内部实例。

所有这些都表明DataProtection API不能在没有DI容器的情况下使用。您应该重新考虑您真的想以这种方式使用它。

答案 1 :(得分:0)

您可以参考Microsoft关于如何将Data Protection用于非DI解决方案(https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/non-di-scenarios?view=aspnetcore-2.2)的建议。

简而言之,请使用静态方法DataProtectionProvider.Create()

using Microsoft.AspNetCore.DataProtection;
static class Program
{
    static void Main()
    {
        var dataProtectionProvider = DataProtectionProvider.Create("Test App");
        var protector = dataProtectionProvider.CreateProtector("Program.No-DI");
        var plainText = "ABCDEFGH";
        var protectedText = protector.Protect(plainText);
    }
}

答案 2 :(得分:0)

由于在幕后实现,无法避免使用 DI。如果您查看“非 DI 示例”DataProtectionProvider.Create(...),您会发现他们使用专用的组合根来提供保护器。

受此启发我写了这个方法:

private static IDataProtectionProvider CreateDataProtectionProviderWithPostgresKeyRepository(string connectionString)
{
    var services = new ServiceCollection();
    var builder = services.AddDataProtection();
    
    builder.Services.AddSingleton<IConfigureOptions<KeyManagementOptions>>(sp =>
    {
        return new ConfigureOptions<KeyManagementOptions>(options =>
        {
            options.XmlRepository = new PostgresDataProtectionKeyRepository(connectionString);
        });
    });
    
    return services.BuildServiceProvider().GetRequiredService<IDataProtectionProvider>();
}

其中 PostgresDataProtectionKeyRepository 只是用于将密钥存储在数据库中的 IXmlRepository 的愚蠢 implementation