Определение текущих проверок безопасности (SQL Server)
В MS SQL Server я всегда ненавидел больше всего на свете то, как работает система безопасности. Контекст безопасности постоянно меняется, если вы смотрите на сервер смешно, и зачастую очень трудно (во всяком случае, для меня) прогнозировать или отлаживать.
Имея дело с проблемой сегодня, я подумал: "Хотел бы я просто добавить в свой код строку, которая отображала бы контекст безопасности, который SQL Server использует при запуске этого кода". Существует ли такая команда? Например, SELECT security_context()
Чтобы быть немного яснее... если я нахожусь в хранимой процедуре и поэтому для меня в контексте безопасности владельца SP, то я хотел бы видеть это. Если я нахожусь в коде, который был вызван sp_executesql, и это приводит к тому, что безопасность находится в контексте учетной записи службы SQL Server, то я хотел бы увидеть это.
По крайней мере, тогда я смогу понять, почему SQL Server считает, что у меня не должно быть доступа к чему-либо.
Спасибо!
ПРИМЕР
-- Set up
CREATE USER Test_User WITHOUT LOGIN
CREATE TABLE Test_Security_Context (my_id INT)
INSERT INTO Test_Security_Context VALUES (1)
DENY SELECT ON Test_Security_Context TO Test_User
GO
CREATE PROCEDURE Test_Security_Context_SP
AS
SELECT SUSER_SNAME()
SELECT * FROM Test_Security_Context -- This will return ok
EXEC('SELECT SUSER_SNAME(); SELECT * FROM Test_Security_Context') -- SUSER_SNAME() will match above but select fails
GO
GRANT EXECUTE ON Test_Security_Context_SP TO Test_User
GO
-- Switch to the new user
SETUSER 'Test_User'
GO
-- Do the test
EXEC Test_Security_Context_SP
GO
-- Clean up
SETUSER
DROP PROCEDURE Test_Security_Context_SP
DROP TABLE Test_Security_Context
DROP USER Test_User
GO
3 ответа
Да, есть такая пара представлений, которая представляет ваш текущий контекст безопасности, учитывая все детали, такие как EXECUTE AS или подпись кода:
sys.login_token
для общего контекста сервераsys.user_token
для текущего контекста базы данных
Каждый доступ, который вы получаете, в конечном итоге выводится из строки в возвращении этих результатов. Обратите внимание, что некоторый доступ является неявным от членства в жестко запрограммированной роли (например, роль базы данных db_datareader или роль сервера sysadmin).
Другое то что:
- цепочка владения не связана с контекстом безопасности: вы не находитесь в "контексте" владельца SP. Цепочка владения просто утверждает, что проверки доступа пропускаются для объектов, принадлежащих тому же владельцу, что и текущий объект (SP, View).
sp_executesql
никак не меняет контекст безопасности
Не уверен, что это то, что вы подразумеваете под контекстом безопасности, но вы можете получить пользователя, связанного с вашим сеансом, например:
select SYSTEM_USER
Это работает как для входа в SQL Server, так и для входа в Windows. Он даже работает внутри хранимых процедур с execute as owner
, Например,
create procedure dbo.Test
with execute as owner
as
select SYSTEM_USER
go
exec dbo.Test
select SYSTEM_USER
Печать:
sa
MyMachine\MyName
Если вы ищете учетную запись Windows, которую SQL Server использует для выполнения действий от вашего имени, вы можете попробовать запустить whoami
из команды вроде:
EXEC sp_configure 'show advanced options', 1
RECONFIGURE
EXEC sp_configure 'xp_cmdshell', 1
RECONFIGURE
EXEC master..xp_cmdshell 'whoami'
Для меня это возвращается nt authority\network service
,
Я думаю, что вы хотите использовать CURRENT_USER
чтобы увидеть текущий контекст безопасности. Вот пример:
SELECT CURRENT_USER AS 'Current User Name';
GO
EXECUTE AS LOGIN = 'junk'
GO
SELECT CURRENT_USER AS 'Current User Name';
GO
REVERT
SELECT CURRENT_USER AS 'Current User Name';
GO
с выводом (примечание: я администратор на моем SQL Server для этого)
Current User Name
------------------
dbo
(1 row(s) affected)
Current User Name
------------------
Junk
(1 row(s) affected)
Current User Name
------------------
dbo
(1 row(s) affected)