代码之家  ›  专栏  ›  技术社区  ›  AngryHacker

如何使用.NET核心web应用程序分发数据保护密钥?

  •  2
  • AngryHacker  · 技术社区  · 5 年前

    我不太清楚数据保护密钥在web场环境中是如何工作的。我没有一个所有服务器都可以使用的公共位置(并且不想处理权限)。因此,我想生成一个密钥并将其与web应用程序一起分发。

    我正在做以下工作,但不确定这是否正确。因此,我在我的dev pc上本地生成一个密钥文件,其中包含:

    var specialFolder = Environment.SpecialFolder.CommonApplicationData;
    var appDataPath = Path.Combine(
         Environment.GetFolderPath(specialFolder),
        "company", 
        "product"
    );
    services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(appDataPath));
    

    key-some-guid.xml 文件然后,我将此文件与我的web应用程序一起分发。

    现在,当我运行web应用程序时,在Startup.Configure services中,将此文件复制到 appDataPath 位置(定义见上文)和呼叫 services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(appDataPath)); .

    这样行吗?还是说我根本上错过了什么?

    1 回复  |  直到 5 年前
        1
  •  1
  •   AngryHacker    5 年前

    回答我自己的问题。以下内容似乎适用于整个web场。从Startup.ConfigureServices调用下面的方法。它假定密钥(在开发人员机器上生成)位于项目根目录下的Keys文件夹中。

    public Startup(IHostingEnvironment env)
    {
        /* skipping boilerplate setup code */
    
        Environment = env;
    }
    
    private IHostingEnvironment Environment { get; set; }
    
    private void ConfigureDataProtection(IServiceCollection services) {
        // get the file from the Keys directory
        string keysFile = string.Empty;
        string keysPath = Path.Combine(Environment.ContentRootPath, "Keys");
        if (!Directory.Exists(keysPath)) {
            Log.Add($"Keys directory {keysPath} doesn't exist");
            return;
        }
    
        string[] files = Directory.GetFiles(keysPath);
        if (files.Length == 0) {
            LLog.Add($"No keys found in directory {keysPath}");
            return;
        } else {
            keysFile = files[0];
    
            if (files.Length >= 2) {
                LLog.Add($"Warning: More than 1 key found in directory {keysPath}.  Using first one.");
            }
        }
    
        // find and optionally create the path for the key storage
        var appDataPath = Path.Combine(
            System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData),
            "companyName",
            "productName"
        );
    
        if (!Directory.Exists(appDataPath)) {
            try {
                Directory.CreateDirectory(appDataPath);
            } catch (Exception ex) {
                Log.Add($"Error creating key storage folder at {appDataPath}.  Error: {ex.Message}");
                return;
            }
        }
    
        // delete any keys from the storage directory
        try {
            foreach (var file in new DirectoryInfo(appDataPath).GetFiles()) file.Delete();
        } catch (Exception ex) {
            Log.Add($"Error deleting keys from {appDataPath}.  Error: {ex.Message}");
            return;
        }
    
        try {
            string targetPath = Path.Combine(appDataPath, new FileInfo(keysFile).Name);
            File.Copy(keysFile, targetPath, true);
        } catch (Exception ex) {
            Log.Add($"Error copying key file {keysFile} to {appDataPath}.  Error: {ex.Message}");
            return;
        }
    
        // everything is in place
        services.AddDataProtection()
            .PersistKeysToFileSystem(new DirectoryInfo(appDataPath))
            .DisableAutomaticKeyGeneration();
    }