.NET Core-自定义配置源(加密文件)

2021-05-28 16:04

阅读:694

标签:ignore   stack   host   tco   this   sort   format   throw   string   

ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddCryptoFile(Path.Combine(AppContext.BaseDirectory, "appsettings.json.crypto"), true);
});

ConfigurationBuilderExtension

    public static class ConfigurationBuilderExtension
    {
        public static IConfigurationBuilder AddCryptoFile(this IConfigurationBuilder configurationBuilder, string path, bool reloadOnChange)
        {
            configurationBuilder.Add(new CryptoFileConfigurationSource(path, reloadOnChange));
            return configurationBuilder;
        }
    }

CryptoFileConfigurationSource

    public class CryptoFileConfigurationSource : IConfigurationSource
    {
        /// 
        /// 路径
        /// 
        public string Path { get; set; }
        /// 
        /// 是否启用热加载
        /// 
        public bool ReloadOnChange { get; set; }
        public CryptoFileConfigurationSource(string path, bool reloadOnChange)
        {
            Path = path;
            ReloadOnChange = reloadOnChange;
        }
        public IConfigurationProvider Build(IConfigurationBuilder builder)
        {
            return new CryptoFileConfigurationProvider(this);
        }
    }

CryptoFileConfigurationProvider

    public class CryptoFileConfigurationProvider : ConfigurationProvider
    {
        private static ConcurrentDictionary CONFIG_CACHE = new ConcurrentDictionary();
        private CryptoFileConfigurationSource _source = null;
        private string _random = string.Empty;
        public CryptoFileConfigurationProvider(CryptoFileConfigurationSource source)
        {
            this._source = source;
            string fileName = IOHelper.GetFileNameNoPath(_source.Path);
            string filePath = _source.Path.Replace(fileName, string.Empty);
            IFileProvider fileProvider = new PhysicalFileProvider(filePath);
            if (_source.ReloadOnChange)
            {
                ChangeToken.OnChange(
                      () => fileProvider.Watch(fileName),
                      () =>
                      {
                          Load();
                      });
            }
            else
            {
                Load();
            }
        }

        public override void Load()
        {
            if (!IOHelper.IsExistFilePath(_source.Path))
            {
                throw new ArgumentException($"{_source.Path}路径不存在");
            }
            string cryptoContent = IOHelper.GetFileContent(_source.Path);
            //解密cryptoContent,获取json
            string json = AESCryptoHelper.Decrypt(cryptoContent);
            byte[] bytes = Encoding.UTF8.GetBytes(json);
            MemoryStream ms = new MemoryStream(bytes);
            this.Data = JsonConfigurationFileParser.Parse(ms);
        }
    }

JsonConfigurationFileParser

    internal class JsonConfigurationFileParser
    {
        private JsonConfigurationFileParser() { }

        private readonly IDictionary _data = new SortedDictionary(StringComparer.OrdinalIgnoreCase);
        private readonly Stack _context = new Stack();
        private string _currentPath;

        private JsonTextReader _reader;

        public static IDictionary Parse(Stream input)
            => new JsonConfigurationFileParser().ParseStream(input);

        private IDictionary ParseStream(Stream input)
        {
            _data.Clear();
            _reader = new JsonTextReader(new StreamReader(input));
            _reader.DateParseHandling = DateParseHandling.None;

            var jsonConfig = JObject.Load(_reader);

            VisitJObject(jsonConfig);

            return _data;
        }

        private void VisitJObject(JObject jObject)
        {
            foreach (var property in jObject.Properties())
            {
                EnterContext(property.Name);
                VisitProperty(property);
                ExitContext();
            }
        }

        private void VisitProperty(JProperty property)
        {
            VisitToken(property.Value);
        }

        private void VisitToken(JToken token)
        {
            switch (token.Type)
            {
                case JTokenType.Object:
                    VisitJObject(token.Value());
                    break;

                case JTokenType.Array:
                    VisitArray(token.Value());
                    break;

                case JTokenType.Integer:
                case JTokenType.Float:
                case JTokenType.String:
                case JTokenType.Boolean:
                case JTokenType.Bytes:
                case JTokenType.Raw:
                case JTokenType.Null:
                    VisitPrimitive(token.Value());
                    break;

                default:
                    throw new Exception("format error");
            }
        }

        private void VisitArray(JArray array)
        {
            for (int index = 0; index 

.NET Core-自定义配置源(加密文件)

标签:ignore   stack   host   tco   this   sort   format   throw   string   

原文地址:https://www.cnblogs.com/fanfan-90/p/14771058.html


评论


亲,登录后才可以留言!