簡體   English   中英

.net 核心 2.2,從 serilog 的用戶機密中讀取設置

[英].net core 2.2, Reading setting from user secrets for serilog

我已經設置了我的解決方案,serilog 從 appsettings.json 讀取值

public void Configure(IApplicationBuilder application, IHostingEnvironment environment, ILoggerFactory loggerFactory)
{
     Logger log = new LoggerConfiguration()
            .ReadFrom.Configuration(Configuration)
            .CreateLogger();
     loggerFactory.AddSerilog(log);

應用程序設置如下所示:

 "Serilog": {
    "Using": [ "Serilog.Sinks.Slack", "Serilog.Sinks.ApplicationInsights" ],
    "MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Microsoft": "Error",
        "System": "Error"
      }

    },
    "WriteTo": [
      {
        "Name": "Slack",
        "Args": {
          "WebHookUrl": "https://hooks.slack.com/services/xxx/yyy/zzz",
          "CustomChannel": "#channel"
        }
      },
      {
        "Name": "ApplicationInsights",
        "Args": {
          "InstrumentationKey": "xxx-xxx-xxx-xxx-xxx",
          "restrictedToMinimumLevel": "Information",
          "telemetryConverter": "Serilog.Sinks.ApplicationInsights.Sinks.ApplicationInsights.TelemetryConverters.TraceTelemetryConverter, Serilog.Sinks.ApplicationInsights"
        }
      }
    ]
  }

所以到這里為止一切都很好,但我不想在我的存儲庫中存儲像 webhook 和 InstrumentationKey 這樣的秘密。 我想從一個安全的地方閱讀它們,比如開發環境中的用戶機密和生產環境中的 Key-vault。 我如何更改它以替換 usersecrets 中的值?

https://learn.microsoft.com/en-us/as.net/core/security/app-secrets?view=as.netcore-2.2&tabs=windows

無論如何,配置會自動被覆蓋嗎?

如果沒有,我知道我可以從秘密中讀取我的配置讓我們說

  webHookUrl = Configuration["Serilog:WriteTo:Slack:WebHookUrl"];

但是我該如何將它應用到 loggerConfig 上呢? 我的意思是,writeTo 部分在設置中是動態的,我應該在代碼中添加它嗎? :\

更新

由於很多人問過,在我的 program.cs 中我有:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseApplicationInsights()
                .UseStartup<Startup>();

根據 Microsoft 文檔,一切都應該有效,因為我有CreateDefaultBuilder並且我正在運行 .net core 2.2。 https://learn.microsoft.com/en-us/as.net/core/security/app-secrets?view=as.netcore-2.2&tabs=windows#access-a-secret

在 ASP.NET Core 2.0 或更高版本中,當項目調用 CreateDefaultBuilder 以使用預配置的默認值初始化主機的新實例時,會在開發模式下自動添加用戶機密配置源 當 EnvironmentName 為 Development 時,CreateDefaultBuilder 調用 AddUserSecrets。

當未調用 CreateDefaultBuilder 時,通過在 Startup 構造函數中調用 AddUserSecrets 顯式添加用戶機密配置源。 僅當應用程序在開發環境中運行時調用 AddUserSecrets

這是我目前用於 ASP.NET Core 3.1 Web 應用程序的內容。 它支持appsettings.json (適用於所有環境)和 Visual Studio 的用戶機密 ( secrets.json ),而無需編寫任何合理的信息(例如用戶機密的唯一 ID)代碼。

Program.cs文件的Main()方法:

public static void Main(string[] args)
{
    var configuration = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json",
            optional: false,
            reloadOnChange: true)
        .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", 
            optional: true,
            reloadOnChange: true)
        .AddUserSecrets<Startup>(optional: true, reloadOnChange: true)
        .Build();

    Log.Logger = new LoggerConfiguration()
        .WriteTo.MariaDB(
            restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Information,
            connectionString: configuration.GetConnectionString("DefaultConnection"),
            tableName: "Logs",
            autoCreateTable: false,
            useBulkInsert: false,
            options: new MariaDBSinkOptions() 
            { 
                LogRecordsExpiration = new TimeSpan(90, 0, 0, 0, 0) 
            })
        .CreateLogger();

    try
    {
        Log.Information("Starting the HostBuilder...");
        CreateWebHostBuilder(args).Build().Run();
    }
    catch (Exception ex)
    {
        Log.Fatal(ex, "The HostBuilder terminated unexpectedly");
    }
    finally
    {
        Log.CloseAndFlush();
    }
}

Program.cs文件的CreateWebHostBuilder()方法:

public static IHostBuilder CreateWebHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel(serverOptions =>
            {
                // Set properties and call methods on options
            })
            .UseStartup<Startup>();
        })
        .UseSerilog();

如果您需要更多的信息,看看這個職位上我的博客。

您可以使用IOptions來做到這一點

首先,我需要定義模型以保存所需的信息

    public class AssetSettings
    {
        public string StorePath { get; set; }
        public string AssetPath { get; set; }
        public string GoogleDriveStorePath { get; set; }
    }

然后我需要在Startup.cs中注冊配置

services.Configure<AssetSettings>(configuration.GetSection("AssetSettings"));

在我的服務中,我可以使用此配置簡單地讀取我的配置

private readonly IOptions<AssetSettings> _assetSettings;

public SettingsRepository(
            IOptions<AssetSettings> assetSettings)
        {
            _assetSettings = assetSettings;
        }

然后只需致電

_assetSettings.Value.StorePath

我在我的機密中復制了完全相同的設置並將其從我的應用設置中刪除,但現在我沒有收到任何日志。 我錯過了什么嗎?

如果您將您的serilog配置appsettings.jsonsecrets.json ,您需要修改ReadFrom.Configuration()Configure從secrets.json閱讀。

var configuration = new ConfigurationBuilder()
          .AddJsonFile("C:\\Users\\Administrator\\AppData\\Roaming\\Microsoft\\UserSecrets\\aspnet-SerilogCore\\secrets.json")
          .Build();//Replace above with path of your secrets.json

Logger log = new LoggerConfiguration()
            .ReadFrom.Configuration(configuration)
            .CreateLogger();
loggerFactory.AddSerilog(log);

我相信@Crowcoder 在他對 OP 的第一條評論中是正確的。 因此,您需要做的是將 appsettings.json 中的結構和部分配置“復制”到主目錄中的 secrets.json 文件中

所以在你的情況下,你會做這樣的事情:

    "Serilog": {

    "WriteTo": [
      {
        "Name": "Slack",
        "Args": {
          "WebHookUrl": "https://hooks.slack.com/services/xxx/yyy/zzz"
        }
      },
      {
        "Name": "ApplicationInsights",
        "Args": {
          "InstrumentationKey": "xxx-xxx-xxx-xxx-xxx"
        }
      }
    ]
  }

所以只有秘密信息存在。

這個答案專門針對“如何使用 Serilog 使用用戶機密? ”。

用戶機密 json 必須反映Serilog部分中的 json 結構。 如果您定義了 2 個 Serilog 接收器,但只有一個用戶機密,則用戶機密 json 仍需要包含兩個接收器(某種程度上 - 請參見下面的示例)。

為什么? 用戶機密必須與 Serilog 配置中“WriteTo”數組的序號索引相匹配。 請參閱以下基於 OP 的 Serilog json 的示例。

注意不需要包含WriteTo[idx].Name值,但包含在內是為了更容易讀取用戶機密。 請記住,User Secrets 不使用接收器的名稱,而是匹配 Serilog WriteTo數組中基於索引的定義; 您不需要在用戶機密中包含WriteTo[idx].Name鍵/值。 但是,如果這樣做,請確保名稱與實際接收器的名稱完全匹配,否則它將覆蓋配置值。

用戶機密 JSON 示例

兩個接收器/WriteTo 都有用戶機密

{
  "SomeOtherConfig": {
    "key": "value"
  },
  "Serilog": {
    "WriteTo": [
      {
        "Name": "Slack",
        "Args": {
          "WebHookUrl": "https://hooks.slack.com/services/my/secret/url",
        }
      },
      {
        "Name": "ApplicationInsights",
        "Args": {
          "InstrumentationKey": "my-secret-instrumentation-key"
        }
      }
    ]
  }
}

只有第一個 sinks/WriteTo 有 User Secrets

由於用戶機密將匹配WriteTo數組的索引,因此只需要包含帶有用戶機密的第一個接收器。

{
  "SomeOtherConfig": {
    "key": "value"
  },
  "Serilog": {
    "WriteTo": [
      {
        "Name": "Slack",
        "Args": {
          "WebHookUrl": "https://hooks.slack.com/services/my/secret/url",
        }
      }
    ]
  }
}

只有最后一個 sinks/WriteTo 有 User Secrets

由於用戶機密將匹配WriteTo數組的索引,因此必須包含第一個接收器占位符和用戶機密,並且需要包含與用戶機密的第二個同步。

{
  "SomeOtherConfig": {
    "key": "value"
  },
  "Serilog": {
    "WriteTo": [
      {
        "Name": "Slack",
      },
      {
        "Name": "ApplicationInsights",
        "Args": {
          "InstrumentationKey": "my-secret-instrumentation-key"
        }
      }
    ]
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM