Проверка подлинности Windows для удаленного пользователя в приложении ASP.NET Core с Entity Framework - PullRequest
0 голосов
/ 28 ноября 2018

Фон

У меня есть приложение ASP.NET Core, работающее в Http.sys для проверки подлинности Windows.

Клиентская часть моего приложения работает с проверкой подлинности Windowsи пользователям предлагается ввести свои учетные данные для входа в Windows при первом доступе к сайту.Все хорошо с этим.

Я использую базу данных SQL Server (размещенную на том же сервере, что и приложение), которая создается Entity Framework с использованием подхода, основанного на коде.В файле startup.cs я запускаю dbContext.migrate(), чтобы убедиться, что база данных обновлена, а затем приложение продолжает работать как обычно.

Проблема

Когда удаленный пользователь взаимодействует с сайтом и выполняет действие, требующее доступа к базе данных, я хотел бы, чтобы эта транзакция базы данных была выполнена под его именем пользователя,

Например, если я запускаю базовое приложение Asp.net на моем сервере как User1, а затем обращаюсь к веб-приложению с компьютера пользователя, который вошел в систему как User2, взаимодействия с базой данных все еще выполняютсяUser1 как пользователь, под которым работает основное приложение.

Я бы хотел, чтобы в этом случае взаимодействия с базой данных могли выполняться с помощью User2 вместо User1.Главным образом для целей регистрации и анализа.

При извлечении экземпляра dbContext я предоставляю ему строку подключения, в которой говорится, что для аутентификации используется SSPI.Есть ли способ включить имя пользователя удаленного пользователя в это соединение, чтобы они могли подключаться к базе данных сами?Я могу легко получить учетные данные / имя пользователя удаленного пользователя из моего контроллера.Я полагаю, что могу использовать что-то под названием Impersonation, но я не уверен в лучших методах реализации этого или если это рекомендуемое решение.

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

Обновление

Благодаря некоторым полезным отзывам я попытался реализовать следующее:

Моя строка подключения установлена ​​так же, как в startup.cs:

services.AddDbContext<MyDbContext>(options => options.UseSqlServer(@"Server=MyServer\MSSQLSERVER;Database=MyDatabase;Trusted_Connection=True;"));

Затем я выполняю такое действие в моем контроллере / классе:

        var values = new List<Values>();

        WindowsIdentity.RunImpersonated(user.AccessToken, () =>
        {
            var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
            optionsBuilder.UseSqlServer(@"Server=MyServer\MSSQLSERVER;Database=MyDatabase;Trusted_Connection=True;");

            using (var ctx = new MyDbContext(optionsBuilder.Options))
            {
                values = (from row in ctx.Table select row).OrderBy(x => x.Id).ToList();
            }
        });

Переменная user передается в функцию и имеет тип WindowsIdentity.

Выполнениекод от localhost работает нормально, но затем при попытке удаленного пользователя возвращает следующую ошибку: System.Data.SqlClient.SqlException: 'A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 0 - No such host is known.)

Обновление 2

Мне удалось устранить эту ошибку с помощьюIP-адрес для строки подключения вместо имени сервера / компьютера.Итак, теперь моя строка подключения выглядит так: @"Server=<IP address>\MSSQLSERVER;Database=ConfigDb;Trusted_Connection=True

Теперь я столкнулся с другой проблемой, когда SQL Server заявляет, что No connection could be made because the target machine actively refused it.Я могу подключиться к SQL Server, используя этого пользователя через SQL Management Studio, но не через мое приложение.

Я обнаружил в EventViewer, что фактическая ошибка связана с SSPI: SSPI handshake failed with error code 0x8009030c, state 14 while establishing a connection with integrated security; the connection has been closed. Reason: AcceptSecurityContext failed. The operating system error code indicates the cause of failure. The logon attempt failed [CLIENT: <named pipe>].Не совсем уверен, почему это не получится.

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

Есть ли способ включить имя пользователя удаленного пользователя в это соединение, чтобы они могли подключаться к базе данных как сами по себе?

Это не будет работать с предоставлением только имени пользователя для строки подключенияВам также нужен пароль для текущего пользователя.

Я полагаю, что могу использовать что-то под названием «Олицетворение», но я не уверен в лучших практиках реализации этого или если это рекомендуемое решение.

Для RunImpersonated,выполните следующие действия:

  • Настройте строку подключения с учетными данными Windows вместо имени пользователя и пароля.

     services.AddDbContext<IISWindowsDbContext>(options =>options.UseSqlServer(@"Server=localhost\MSSQLSERVER01;Database=IISWindows;Trusted_Connection=True;"));
    
  • Использование

        public IActionResult About()
    {
        IList<Blog> blogs = new List<Blog>();
        var user = (WindowsIdentity)User.Identity;
        WindowsIdentity.RunImpersonated(user.AccessToken, () =>
        {
            var impersonatedUser = WindowsIdentity.GetCurrent();
            blogs = _context.Blogs.ToList();
        });
        return Ok(blogs);
    }
    
0 голосов
/ 28 ноября 2018

Документы ASP.NET Core охватывают именно эту тему.

Проще говоря, ASP.NET Core не реализует олицетворение.В нем есть пример обходного решения, использующего WindowsIdentity, но у него есть свои ограничения, и его следует использовать только для относительно простых операций.

Существует также пакет NuGet , который может помочь вам получить некоторыебольше функциональности, но все еще ограничено.

...