Как получить доступ и использовать секреты пользователя в приложении Saturn

Изменить: вот некоторые адаптации к ответу Кенига Лира на случай, если кто-то еще наткнется на этот вопрос:

чтобы добавить секреты пользователя в приложение, я использовал этот код, где идентификатор, используемый config.AddUserSecrets - это идентификатор секретов, который добавляется в Server.fsproj с помощью dotnet user-secrets init.

app
    .ConfigureAppConfiguration(
        System.Action<Microsoft.Extensions.Hosting.HostBuilderContext,IConfigurationBuilder> ( fun ctx config ->
            config.AddUserSecrets("6de80bdf-2a05-4cf7-a1a8-d08581dfa887") |> ignore
        )
)
|> run

Затем секрет может быть использован маршрутизатором через:

 forward "/api" (fun next ctx ->

        let settings = ctx.GetService<IConfiguration>()
        let cString = settings.["Some:ConnectionString"]

        webApp cString next ctx

    )

Исходный вопрос:

Я пытаюсь понять, как получить доступ к секретам пользователей, но не могу полностью перевести пример, предоставленный Microsoft.

допустим, у меня есть Saturn, работающий в среде БЕЗОПАСНОГО стека (в данном случае, скорее всего, не имеет значения). У меня есть веб-приложение, которое принимает строку подключения, а затем обрабатывает запросы, используя предоставленную строку подключения для доступа к БД:

let router connectionString = forward "/api" (webApp connectionString)

и секрет пользователя, содержащий строку подключения, которую я инициировал с помощью dotnet user-secrets set:

{
  "Some:ConnectionString": "Data Source=..."
}

и application который использует роутер:

let app = application {
    url ("https://0.0.0.0:" + port.ToString() + "/")
    use_router (router )
}

Что я пытаюсь сделать, так это извлечь секрет пользователя и передать его маршрутизатору. Чего я, кажется, не понимаю, так это где и как выполнять инъекцию зависимостей, которую обычно делает ASP.NetCore (см. Где пользовательский секрет настраивается черезConfiguration API в примере MS Docs.).

Что очень близко к тому, что я пытаюсь сделать, это этот раздел из примера:


public class Startup
{
    private string _connection = null;

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        var builder = new SqlConnectionStringBuilder(
            Configuration.GetConnectionString("Movies"));
        builder.Password = Configuration["DbPassword"];
        _connection = builder.ConnectionString;
    }

    public void Configure(IApplicationBuilder app)
    {
        app.Run(async (context) =>
        {
            await context.Response.WriteAsync($"DB Connection: {_connection}");
        });
    }
}

Первая проблема в том, что я не могу найти, как получить Configuration объект, содержащий GetConnectionString метод. Но даже если бы я мог это сделать, я бы настроил этот раздел черезservice_config операция в applicationмонада правильно? Но тогда я не могу использовать полученную строку подключения для роутера, потому чтоuse_router операция отделена от него.

Я использую Saturn 0.14.1 на netcoreapp/asp.netcore 3.1 .

Любая помощь будет принята с благодарностью!

1 ответ

Решение

Вы должны иметь возможность использовать метод ConfigureAppConfiguration:

open Microsoft.Extensions.Configuration
open Microsoft.Extensions.Configuration.UserSecrets

let configureAppConfiguration  (context: WebHostBuilderContext) (config:IConfigurationBuilder) =  
    config
        .AddUserSecrets()

app
   .ConfigureAppConfiguration(configureAppConfiguration)
   .run

Внутри вашего роутера вы можете использовать его так:

let webApp = router {
    get "/" (fun next ctx ->
        task {
            let settings = ctx.GetService<IConfiguration>()
            let s = settings.["Some:ConnectionString"]
            ...
        })
}
Другие вопросы по тегам