Фон
У меня есть приложение 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>]
.Не совсем уверен, почему это не получится.