SUSER SNAME: примеры (SQL)

Функция SUSER_SNAME в SQL Server: примеры и особенности
Раздел: Функции безопасности и шифрования, Безопасность
SUSER_SNAME([server_user_sid]): nvarchar(128)

Описание функции SUSER_SNAME

Функция SUSER_SNAME в Microsoft SQL Server возвращает имя входа, связанное с идентификатором безопасности (SID). Эта функция используется для аудита, логирования действий пользователей, а также для отображения и фильтрации данных в зависимости от контекста безопасности.

Функция может быть вызвана с одним необязательным аргументом:

  • server_user_sid (тип varbinary(85)) — идентификатор безопасности (SID) имени входа на уровне сервера. Если аргумент не указан, функция возвращает имя входа текущего пользователя. Если указан NULL, также возвращает имя текущего пользователя.

Возвращаемое значение имеет тип nvarchar(128). Если указанный SID не найден в системном представлении sys.server_principals, функция возвращает NULL. Для встроенных системных учетных записей (например, NT AUTHORITY\SYSTEM) функция возвращает их имена.

Примеры использования SUSER_SNAME

Базовый вызов для получения текущего пользователя:

SELECT SUSER_SNAME();
DOMAIN\User1

Использование с конкретным SID:

SELECT SUSER_SNAME(0x010500000000000515000000BB0AA5FE2E7DCC8B1B5B5DCFD3010000);
DOMAIN\ServiceAccount

Попытка получить имя для несуществующего SID:

SELECT SUSER_SNAME(0x00);
NULL

Похожие функции в MS SQL

В MS SQL Server существуют другие функции для работы с контекстом безопасности:

  • SUSER_SID — возвращает SID для указанного имени входа. Является обратной функцией к SUSER_SNAME.
  • SYSTEM_USER — возвращает имя входа текущего пользователя, но только в контексте базы данных, а не сервера. Аналогична SUSER_SNAME() без параметров, но семантически больше относится к пользователям базы данных.
  • ORIGINAL_LOGIN — возвращает имя входа, с которым пользователь первоначально подключился к серверу, что полезно при аудите в среде с олицетворением (EXECUTE AS).

Функцию SUSER_SNAME предпочтительнее использовать для аудита на уровне сервера и когда известен SID. Для работы в контексте конкретной базы данных чаще применяется SYSTEM_USER.

Типичные ошибки при использовании

Ошибка неявного преобразования типа: Передача строкового значения вместо varbinary.

SELECT SUSER_SNAME('0x010500000000000515000000BB0AA5FE2E7DCC8B1B5B5DCFD3010000');
Ошибка преобразования типа данных.

Неправильная интерпретация результата: Когда функция возвращает NULL, это может означать как несуществующий SID, так и то, что текущий пользователь — системный (например, при выполнении задания агента от имени системной учетной записи).

-- Если выполняется от имени NT AUTHORITY\SYSTEM
SELECT SUSER_SNAME();
NT AUTHORITY\SYSTEM

Ошибок нет, но результат может быть неожиданным, если логика приложения предполагает только доменных пользователей.

История изменений функции

В SQL Server 2012 и более поздних версиях функция SUSER_SNAME была расширена для поддержки содержащихся пользователей базы данных. Теперь она может возвращать имена для пользователей, которые не имеют сопоставленного имени входа на уровне сервера, если они аутентифицируются через содержащую базу данных.

Также, начиная с SQL Server 2005, функция всегда возвращает nvarchar(128), в то время как в более ранних версиях возвращаемый тип мог быть nvarchar(256).

Расширенные примеры применения

Использование в триггере для аудита изменений:

Пример sql
CREATE TABLE dbo.AuditLog (
    ID INT IDENTITY PRIMARY KEY,
    ChangeDate DATETIME DEFAULT GETDATE(),
    LoginName NVARCHAR(128) DEFAULT SUSER_SNAME(),
    TableName NVARCHAR(128),
    ActionType NVARCHAR(10)
);

Определение владельца сессии по SID из системных представлений:

Пример sql
SELECT 
    session_id,
    SUSER_SNAME(security_id) AS LoginName
FROM sys.dm_exec_sessions
WHERE program_name LIKE '%Management Studio%';
session_id  LoginName
----------- ------------------
52          DOMAIN\AdminUser

Сопоставление SID из таблицы с именами входа:

Пример sql
-- Предположим, есть таблица с SID пользователей
DECLARE @UserSIDs TABLE (UserSID varbinary(85));
INSERT INTO @UserSIDs VALUES (0x010500...);

SELECT 
    UserSID,
    SUSER_SNAME(UserSID) AS MappedLogin
FROM @UserSIDs;

Использование в сочетании с ORIGINAL_LOGIN для обнаружения олицетворения:

Пример sql
SELECT 
    SUSER_SNAME() AS CurrentContext,
    ORIGINAL_LOGIN() AS OriginalLogin;
-- Результат после EXECUTE AS USER='AnotherUser':
-- CurrentContext: AnotherUser
-- OriginalLogin: DOMAIN\AdminUser

Аналоги в других СУБД и языках

MySQL: Функция USER() или CURRENT_USER() возвращает имя пользователя и хост.

SELECT USER();
user1@localhost

Oracle: Функция USER или SYS_CONTEXT('USERENV', 'SESSION_USER').

SELECT USER FROM dual;
SCOTT

PostgreSQL: Функция CURRENT_USER возвращает имя текущего пользователя.

SELECT CURRENT_USER;
postgres

SQLite: Нет встроенной функции, так как SQLite не имеет системы управления пользователями на уровне сервера.

Sybase ASE: Функция SUSER_NAME() аналогична MS SQL.

Основное отличие MS SQL SUSER_SNAME — возможность получать имя по SID, что уникально для серверов Microsoft.

MS SQL SUSER_SNAME function comments

En
SUSER SNAME Returns the login name associated with a security identification number (SID)