SQL Server и проверка подлинности Windows

Скачать ADO.NET

Аутентификация определяет, какая идентичность подключается к SQL Server. Разрешения базы данных определяют, что эта идентичность может делать после подключения. Выберите аутентификацию для среды, в которой работает ваше приложение, и настройте отдельно шифрование и проверку сертификатов Transport Layer Security (TLS ).

Режим аутентификации сервера в SQL Server отличается от учётных данных, которые отправляет ваш клиент:

  • Режим проверки подлинности Windows принимает учетные записи Windows.
  • Смешанный режим принимает идентификаторы Windows, а также имена пользователей и пароли SQL Server.

Установка строки подключения клиента не меняет режим аутентификации сервера. Для настройки сервера см. Выберите режим аутентификации.

Сценарии проверки подлинности

Предпочтительнее использовать аутентификацию, не требующую пароля, которым управляет приложение, если ваша среда это поддерживает.

Среда применения Выбор аутентификации
Доменная среда с соответствующей идентичностью Windows. Integrated Security=true. SQL Server может находиться на другом компьютере в доверенной среде.
Приложение Linux или macOS с заданным идентификатором домена. Интегрированная безопасность с требованиями Kerberos на клиенте и сервере.
Локальная разработка Windows с LocalDB. Интегрированная безопасность под идентификацией местного разработчика.
Приложение, размещенное в Azure, с поддержкой Microsoft Entra в конечной точке SQL. Управляемая идентификация или другой подходящий режим аутентификации Microsoft Entra.
Среда, требующая SQL-учетных данных. SQL-аутентификация с наименее привилегированными учетными данными, полученными из защищённой конфигурации или секретного хранилища.

Приложение, выходящее в Интернет, не обязательно требует SQL-аутентификации. Вход веб-пользователя в систему и учётные данные базы данных приложения — это два отдельных решения.

Подключитесь с помощью проверка подлинности Windows

Используйте идентификатор, под которым работает приложение:

Server=tcp:<server>,1433;Database=<database>;Integrated Security=true;Encrypt=true;TrustServerCertificate=false;MultiSubnetFailover=true;

Trusted_Connection=true — синоним Integrated Security=true. Если включена интегрированная безопасность, User ID и Password в строке подключения игнорируются. Они не выбирают другого пользователя Windows.

Служба обычно подключается от имени своей учётной записи службы, а не от имени пользователя, работающего через её веб-интерфейс. Предоставьте права доступа к базе данных целевой учетной записи службы. Если вам требуется делегирование удостоверения личности конечного пользователя между компьютерами, явно настройте и проверьте делегирование Kerberos.

Требования к платформе

Client Требования и поведение
.NET Framework на Windows. Использует нативную сетевую систему Windows и интерфейс поставщика поддержки безопасности (SSPI).
Современный .NET на Windows. По умолчанию использует нативную сеть. Windows Negotiate выбирает Kerberos при настройке; он может вернуться к NT LAN Manager (NTLM).
Современный .NET на Linux или macOS. Использует управляемые сети и .NETNegotiateAuthentication. Настройте клиент Kerberos, область, имя главного сервиса (SPN), а также действительные учетные данные или кэш билетов.

Интегрированная безопасность не заменяет настройки доверия домена, разрешения системы доменных имён (DNS), синхронизации времени и SPN SQL Server. В Linux перед запуском приложения получите билет с помощью средств Kerberos этой платформы, например kinit. Не думайте, что резервный вариант NTLM для Windows доступен на клиенте, не входящем в Windows. См. Регистрировать SPN для соединений Kerberos.

Чтобы проверить схему аутентификации для вашего текущего SQL Server соединения, выполните этот Transact-SQL (T-SQL) запрос:

SELECT auth_scheme
FROM sys.dm_exec_connections
WHERE session_id = @@SPID;

Доступ к этому диагностическому просмотру зависит от прав доступа сервера. Одна успешная связь не доказывает, что использовался Kerberos, а не NTLM.

Для приложений, которые должны управлять согласованием контекста безопасности, SspiContextProvider поддерживается кастомная реализация SSPI. Это расширенная точка расширяемости для таких сценариев, как настраиваемая аутентификация Kerberos или явные учетные данные NTLM. Это не режим аутентификации по строкам соединения и не может быть комбинирован с AccessToken или AccessTokenCallback.

Пользовательские поставщики контекста интерфейса поставщика поддержки безопасности (SSPI)

SspiContextProvider Абстрактный класс является основой для всех поставщиков контекста SSPI. Чтобы создать пользовательский провайдер, унаследуйте класс от SspiContextProvider и переопределите метод GenerateContext. Назначьте экземпляр вашего провайдера свойству SspiContextProvider объекта SqlConnection перед открытием соединения.

GenerateContext Метод вызывается во время рукопожатия по аутентификации SSPI. Он получает входящий блок аутентификации от сервера, объект записи в буфер для исходящего ответного blob и объект SspiAuthenticationParameters с метаданными соединения, такими как:

  • Resource — имя субъекта-службы сервера (SPN).
  • ServerName - Имя источника данных.
  • DatabaseName - Целевая база данных, если указана.
  • UserId — идентификатор пользователя, если он указан в строке подключения.
  • Password- Пароль, если он указан в строка подключения.

Важные рекомендации.

  • Задайте свойство SspiContextProvider перед открытием соединения. Попытка установить его на открытое или подключённое соединение вызывает исключение InvalidOperationException.
  • Этот SspiContextProvider экземпляр является частью ключа, используемого для идентификации пулов соединений. Избегайте создания нового SspiContextProvider экземпляра для каждого SqlConnection , так как каждый новый провайдер создаёт новый пул. Ссылайтесь на тот же экземпляр провайдера для подключений, которые вы хотите, чтобы учитывались при пуллинге.
  • Пользовательский SspiContextProvider должен аутентифицироваться с тем же контекстом безопасности для тех же входных параметров. Если контекст безопасности отличается, для запроса на соединение может быть возвращено объединённое соединение с неправильным контекстом безопасности.
  • SspiContextProvider не может использоваться вместе с аутентификацией на основе токенов. Если поставить его рядом с AccessToken или с AccessTokenCallback, выбрасывает InvalidOperationException, независимо от того, какое свойство вы задаёте первым.

Example

NegotiateAuthentication требует .NET 7 или новее, поэтому этот пример не компилируется на .NET Framework. Для провайдера .NET Framework реализуйте GenerateContext с использованием платформенного API SSPI.

Следующий пример показывает пользовательский поставщик контекста SSPI, который использует NegotiateAuthentication для выполнения аутентификации:

using System;
using System.Buffers;
using System.Net.Security;
using Microsoft.Data.SqlClient;

class CustomSspiContextProvider : SspiContextProvider
{
    private NegotiateAuthentication? _auth;

    protected override bool GenerateContext(
        ReadOnlySpan<byte> incomingBlob,
        IBufferWriter<byte> outgoingBlobWriter,
        SspiAuthenticationParameters authParams)
    {
        _auth ??= new NegotiateAuthentication(
            new NegotiateAuthenticationClientOptions
            {
                Package = "Negotiate",
                TargetName = authParams.Resource,
            });

        byte[]? blob = _auth.GetOutgoingBlob(
            incomingBlob, out NegotiateAuthenticationStatusCode statusCode);

        if (statusCode is not NegotiateAuthenticationStatusCode.Completed
            and not NegotiateAuthenticationStatusCode.ContinueNeeded)
        {
            return false;
        }

        if (blob is not null)
        {
            outgoingBlobWriter.Write(blob);
        }

        return true;
    }
}

Назначьте провайдера соединению перед его открытием:

using var connection = new SqlConnection(
    "Server=myServer;Database=myDatabase;Integrated Security=true;Encrypt=True;");
connection.SspiContextProvider = new CustomSspiContextProvider();
connection.Open();

Вопросы безопасности

Имейте в виду следующие вопросы безопасности при внедрении пользовательского SSPI-провайдера контекста:

  • Проверяйте все входные данные. Всегда проверяйте входящие BLOB-объекты и параметры аутентификации перед их обработкой. Искажённые или неожиданные данные должны быть отклонены путем возврата false из GenerateContext.
  • Защитите учетные данные. Объект SspiAuthenticationParameters может содержать чувствительные значения, такие как UserId и Password. Не фиксируйте, не сохраняйте и не передавайте эти значения незащищённым образом.
  • Используйте проверенные библиотеки аутентификации. По возможности делегируйте логику аутентификации в хорошо проверенные библиотеки, например NegotiateAuthentication , не реализуйте криптографические протоколы самостоятельно.
  • Освободите ресурсы. Если ваш провайдер выделяет неуправляемые ресурсы или контексты аутентификации, внедрите IDisposable, и обеспечьте правильную очистку. SqlClient не освобождает экземпляр SspiContextProvider. Освободите провайдер, когда ваше приложение больше не нуждается в нем.
  • Ограничьте пакет аутентификации. Используйте только пакеты аутентификации, подходящие для вашей среды (например Negotiate , или Kerberos). Передавайте только входные данные из доверенных источников и конфигурацию в пакет аутентификации.
  • Проведите тщательное тестирование. Убедитесь, что ваш провайдер работает корректно при всех ожидаемых условиях, включая продление токенов, пул соединений и сценарии аварийного переключения.

Microsoft не проверяет и не проводит аудит кастомных SspiContextProvider реализаций, а также не гарантирует безопасность подключений, аутентифицированных через настраиваемого поставщика. Любые уязвимости, возникающие при кастомной реализации, — ваша ответственность.

Типы имен для входа

Вход даёт идентификационному доступу к серверу. Пользователь базы данных представляет идентичность внутри базы данных. Сопоставьте предполагаемый логин или группу с пользователем базы данных, затем предоставите только необходимые права через роли базы данных.

SQL Server поддерживает вход в аккаунты Windows, групповые входы Windows и SQL-входы. Группа Windows позволяет администраторам управлять членством без создания отдельного входа на SQL Server для каждого человека. Вход с использованием сертификатов и асимметричных ключей, применяемых для подписания кода, не относится к интерактивным учётным данным для подключения.

Пользователи содержащейся базы данных и руководители Microsoft Entra имеют разные требования к предоставлению. См. Principals и документацию по аутентификации конечной точки вместо того, чтобы предполагать, что каждому пользователю нужна учётная запись SQL.

Режим смешанной проверки подлинности

Используйте SQL-аутентификацию только на конечной точке, настроенной для её приёма. Укажите User ID и Password, отключите интегрированную безопасность и оставьте проверку сертификатов включённой. Authentication=Sql Passwordявно выбирается аутентификация по паролю SQL; не выбирается аутентификация по паролю Microsoft Entra.

Следующий пример консоли .NET использует Microsoft.Data.SqlClient. Устанавливайте SQL_SERVER, SQL_DATABASE, SQL_USER_IDи SQL_PASSWORD через вашу среду разработки или механизм секретного введения данных. SQL_SERVER должен содержать конечную точку TCP (Transmission Control Protocol), такую как tcp:sql-server.contoso.com,1433. Не выводите пароль или полную строку подключения.

using Microsoft.Data.SqlClient;

static string Required(string name) =>
    Environment.GetEnvironmentVariable(name)
    ?? throw new InvalidOperationException($"Set {name} before running.");

var options = new SqlConnectionStringBuilder
{
    DataSource = Required("SQL_SERVER"),
    InitialCatalog = Required("SQL_DATABASE"),
    Authentication = SqlAuthenticationMethod.SqlPassword,
    UserID = Required("SQL_USER_ID"),
    Password = Required("SQL_PASSWORD"),
    Encrypt = SqlConnectionEncryptOption.Mandatory,
    TrustServerCertificate = false,
    MultiSubnetFailover = true
};

using var connection = new SqlConnection(options.ConnectionString);
await connection.OpenAsync();
using var command = new SqlCommand("SELECT DB_NAME();", connection);
Console.WriteLine(await command.ExecuteScalarAsync());

Запрос печатает имя связанной базы данных. Используйте SqlConnectionStringBuilder вместо объединения учетных данных в строку. Конструктор скрывает значения строк соединения; он не решает, какие серверы, базы данных или разрешения должно быть разрешено вашим приложением.

Оставьте Persist Security Info=false по умолчанию. Храните производственные секреты в защищённом секретном магазине, ограничивайте тех, кто может их читать, и меняйте их. Не используйте идентификатор администратора или владельца базы данных для рутинных запросов приложений.

Microsoft Entra и ограничения сервиса

Integrated Security=trueаутентифицирует идентичность Windows в SQL Server. Authentication=Active Directory Integrated получает токен Microsoft Entra. Они не взаимозаменяемы.

База данных SQL Azure использует аутентификацию SQL или Microsoft Entra вместо обычной интегрированной аутентификации Windows. База данных SQL в Microsoft Fabric поддерживает только удостоверения Microsoft Entra; аутентификация SQL и имена входа SQL не поддерживаются. Используйте статью Microsoft Entra для подключений на основе токенов.