.Net Core 2 WebApi для SQL Server с использованием Active Directory

Я работаю над проектом, в котором использую .net core 2.

У меня есть клиентское приложение, которое вызывает веб-API, при этом API взаимодействует с базой данных (SQL Server 2017). Поскольку это только внутреннее (интранет) приложение, мы используем AD (Active Directory) в качестве метода аутентификации и безопасности приложения.

При локальной работе приложение и БД правильно используют данные пользователя (т. е. имя и данные для входа), передаются через приложение и используются API для связи с базой данных. Затем вызов базы данных использует suser_name для автоматической записи имени пользователя в таблицу. Нам нужно знать действия отдельных пользователей, а не использовать логин SQL Server, который используется приложением в целом.

Когда приложение перемещается в тестовую среду, веб-сервер (IIS8.5), который содержит клиент и API в разных виртуальных каталогах, и база данных, которая находится на другом сервере. Оба сервера находятся в одном домене (NL-TEST). При обновлении строки подключения из: Server=LT017180;Database=Payments; Интегрированная безопасность = SSPI; на Сервер=тестовый сервер;База данных=Платежи; Интегрированная безопасность = SSPI; он не будет подключаться к базе данных.

Я подтвердил, что пользователь (например, NL-TEST\Joe_Bloggs) настроен в разделе безопасности сервера базы данных и имеет доступ к базе данных и находится в домене NL-TEST в качестве пользователя (я установил для него значение db_owner, просто попытаться заставить его работать).

Я подтвердил, что у API есть учетные данные пользователей. Как мне получить учетные данные для базы данных, чтобы он вошел в систему как пользователь и получил доступ к базе данных?

Пример моего кода: Клиент Запуск

public Startup(IConfiguration configuration, IHostingEnvironment env)
    {
        Configuration = configuration;
        Environment = env;
    }

    public IConfiguration Configuration { get; }
    private IHostingEnvironment Environment { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {

        services.AddMvc();
        services.Configure<Entities.APIs>(Configuration.GetSection("APIURLs"));
        services.AddPolicies(Configuration.GetSection("Policies").Get<Policies>());
        services.AddAuthentication(IISDefaults.AuthenticationScheme);
        services.AddDistributedMemoryCache();
        services.AddSession(options =>
        {
            options.IdleTimeout = TimeSpan.FromDays(1);
        });

    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();
        app.UseAuthentication();

        app.UseSession();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

API

public IDbConnection Connection => new SqlConnection(_connectionString);

    [HttpGet("payment/employee/{id}")]
    public IEnumerable<PaymentDTO> GetByEmployeeId(Int64 id)
    {
        using (IDbConnection dbConnection = Connection)
        {
            var parameters = new DynamicParameters();
            parameters.Add("EmployeeNo", id, DbType.Int64);

            dbConnection.Open();
            var payments = dbConnection.Query<PaymentDTO>("api.GetPaymentsForEmployeeNo", parameters, commandType: CommandType.StoredProcedure);
            dbConnection.Close();
            return payments;
        }
    }

Ajax-вызов API

        var onAjaxSuccess = function (data) {

       // do something
    };

    $.ajax({
        headers: {
            'Accept': 'application/json'
        },
        contentType: 'application/json',
        url: href,
        type: "POST",
        cache: false,
        error: function (result) {
            // record an error
        },
        success: onAjaxSuccess,
        xhrFields: {
            withCredentials: true
        },
        processData: false
    });

Вызов контроллера API:

private static readonly HttpClient Client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true});

        private static async Task<PaymentDTO> GetPaymentsDetails(Int64 paymentId)
    {
        var url = new Uri(ApiUrls.PaymentsAPI + "/payments/payment/" + paymentId);

        Client.DefaultRequestHeaders.Accept.Clear();
        Client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));
        HttpResponseMessage response = await Client.GetAsync(url);
        if (response.IsSuccessStatusCode)
        {
            var jsonString = await response.Content.ReadAsStringAsync();
            var payments = JsonConvert.DeserializeObject<List<PaymentDTO>>(jsonString);
            var payment = payments[0];

            return payment;
        }
        return new PaymentDTO();
    }

Мне не хватает настройки или оболочки?


person Paul Beare    schedule 22.06.2018    source источник


Ответы (1)


До .NET Core все, что вам нужно было сделать, это отключить анонимную аутентификацию, включить аутентификацию Windows и включить олицетворение (либо через web.config проекта, либо при развертывании в IIS вы также можете сделать это в настройках аутентификации сайт.)

.NET Core отказался от олицетворения, поэтому это больше невозможно. Без возможности использовать олицетворение при развертывании в IIS приложение (и подключения к базе данных) выполняется как пользователь AppPool этого сайта (а не фактический пользователь, просматривающий сайт, даже если включена проверка подлинности Windows).

Они предлагают несколько устаревшее решение для олицетворения пользователя, прошедшего проверку подлинности Windows, но на самом деле это не рекомендуется, особенно для тяжелых единиц работы. Прочтите раздел Олицетворение внизу: https://docs.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-3.1.&tabs=visual-studio

Альтернативные решения этой проблемы:

  • Разработайте свой собственный экран входа в систему, чтобы получить ссылку на учетные данные пользователей и использовать их для подключения к базе данных (очевидно, это должно быть реализовано безопасным способом).
  • Реализовать аутентификацию OAuth
person J.D.    schedule 29.10.2020