我试图实现一个名为'CryptographyConfigProvider'的自定义JsonConfigurationProvider,如果它被加密,它会从流中解密JSON。
我从JsonConfigurationProvider继承并实现了一个自定义的Load方法。
我在Program.cs中使用它:
var configuration = new ConfigurationBuilder()
.AddEncryptedJsonFile($"appsettings.{enviromentValue}.json", optional: true, reloadOnChange: false)
.Build();
此调用执行我的自定义实现。 (见下文)
但是在此ASP.NET Core尝试再次访问appsettings文件之后:
webHostBuilder.Build().Run();
异常表示调用了普通的JsonConfigurationProvider而不是我继承的类CryptographyConfigProvider。
System.FormatException: Could not parse the JSON file. Error on line number '0': 'EncryptedString'.
---> Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: S. Path '', line 0, position 0.
at Newtonsoft.Json.JsonTextReader.ParseValue()
at Newtonsoft.Json.Linq.JObject.Load(JsonReader reader, JsonLoadSettings settings)
at Microsoft.Extensions.Configuration.Json.JsonConfigurationFileParser.Parse(Stream input)
at Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider.Load(Stream stream)
--- End of inner exception stack trace ---
at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load(Boolean reload)
at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load()
at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors)
at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
at Main(String[] args) in Program.cs
有人知道为什么ASP.NET Core使用普通的JsonConfigurationProvider吗?
这是我的实施:
public static class DecryptionConfigProviderExtension
{
public static IConfigurationBuilder AddEncryptedJsonFile(this IConfigurationBuilder builder, string path, bool optional, bool reloadOnChange)
{
return builder.AddJsonFile(s =>
{
s.FileProvider = null;
s.Path = path;
s.Optional = optional;
s.ReloadOnChange = reloadOnChange;
s.ResolveFileProvider();
});
}
public static IConfigurationBuilder AddJsonFile(this IConfigurationBuilder builder, Action<CryptographyConfigurationSource> configureSource) => builder.Add(configureSource);
}
public class CryptographyConfigurationSource : JsonConfigurationSource, IConfigurationSource
{
public override IConfigurationProvider Build(IConfigurationBuilder builder)
{
EnsureDefaults(builder);
return new CryptographyConfigProvider(this);
}
}
public class CryptographyConfigProvider : JsonConfigurationProvider
{
private const string EncryptionKey = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456";
private AesCryptography _aesCryptography;
public CryptographyConfigProvider(CryptographyConfigurationSource cryptographyConfigurationSource) : base(cryptographyConfigurationSource)
{
_aesCryptography = new AesCryptography();
}
public override void Load(Stream stream)
{
Data = UnencryptConfiguration(stream);
}
private IDictionary<string, string> UnencryptConfiguration(Stream stream)
{
var reader = new StreamReader(stream);
var text = reader.ReadToEnd();
var jsonString = DecryptIfEncrypted(text);
using (MemoryStream jsonStream = new MemoryStream())
{
var parser = new JsonConfigurationFileParser();
StreamWriter writer = new StreamWriter(jsonStream);
writer.Write(jsonString);
writer.Flush();
jsonStream.Position = 0;
return parser.Parse(jsonStream);
};
}
private string DecryptIfEncrypted(string text)
{
var jsonString = string.Empty;
try
{
jsonString = _aesCryptography.DecryptString(text, EncryptionKey);
}
catch
{
jsonString = text;
}
return jsonString;
}
}
答案 0 :(得分:2)
从.NET Core 2.0开始,Method doSomethingWithData:<OCMBlockConstraint: 0x7ff252a65a10> fromString:<OCMBlockConstraint: 0x7ff252a5f170> success:<OCMAnyConstraint: 0x7ff252a38350> failure:<OCMAnyConstraint: 0x7ff252a5f200> was not invoked.
会自动加载。如果你已加密它,那么框架可能会解析它。
appsettings.{env.EnvironmentName}.json
MetaPackages/src/Microsoft.AspNetCore/WebHost.cs
我会尝试将您的文件命名为其他内容。
我的团队最近实施的另一种解决方案是将秘密移至app.config并使用protected configuration对其进行加密。自定义配置提供程序读取应用程序设置(例如.ConfigureAppConfiguration((hostingContext, config) =>
{
...
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
...
)并将它们提供给Core框架。
答案 1 :(得分:1)
必须创建自定义提供程序并使用老式的XML配置文件来处理加密设置,这很疯狂。这应该由IMO框架来处理。
同时,我对this question的回答是一种非常简单直接的方法,用于加密设置文件中的值。它使用现有的JSON提供程序,首选的.Net Core加密技术,并且对DI友好。
希望有帮助!