2010-08-02 3 views
4

Одна вещь, которую я всегда ненавидел больше, чем что-либо в MS SQL Server, - это способ обеспечения безопасности. Контекст безопасности постоянно переключается, если вы смотрите на сервер смешно, и часто это очень сложно (для меня в любом случае) для прогнозирования или отладки.Определение текущих проверок безопасности (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 

ответ

4

Да, есть такая пара взглядов, которая представляет свой текущий контекст безопасности, учитывая все детали, как EXECUTE AS или код подписи:

  • sys.login_token для сервера широкий контекст
  • sys.user_token для текущего контекста базы данных

Каждый полученный вами доступ в конечном итоге получается из строки в результате возвращения этих результатов.Обратите внимание, что некоторый доступ подразумевается из членства в жесткой кодировке (например, роль базы данных db_datareader или роль сервера sysadmin).

Другое, что это:

  • цепочки владения не связана с контекстом безопасности: вы не под «контекста» владельца SP. Собственная цепочка просто заявляет, что проверки доступа пропускаются для объектов, принадлежащих тому же владельцу, что и текущий объект (SP, View).
  • sp_executesql делает не изменить контекст безопасности в любом случае
+0

+ 1 Wow. Один вопрос: почему login_token для 'builtin \ administrators' говорит' deny only'? Я ожидал, что это послужило причиной большинства моих грантов! – Andomar

+1

@Andomar: Я думаю, это Vista LUA, это изменяет токен администратора но я не уверен. –

+0

Может быть, с моей терминологией, с плохой терминологией. Я ищу: «Вот почему у вас нет прав» и «Вот почему у вас есть разрешения». м вероятно, слишком много, но я знаю, что я не одинок в своей ненависти к попытке распутать такие ошибки безопасности, особенно когда речь идет о междоменном доступе, динамическом SQL и т. д. –

1

Не уверен, если это то, что вы имеете в виду контекст безопасности, но вы можете получить пользователь, связанный с вашей сессии, как:

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.

+0

Хотя SUSER_SNAME() является пользователь, связанный с сессией, что не будет оставаться действительным, когда вы находитесь в хранимой процедуре (которая использует контекст безопасности владельца SP) или когда вы используете динамический SQL, такой как EXEC (@cmd). Не говоря уже о полном беспорядке цепочки владения. :( –

+1

@Tom H: Оба 'suser_sname()' и 'SYSTEM_USER', похоже, хорошо работают для хранимых процедур (пример добавлен в ответ.) Возможно, вы можете опубликовать пример, где они не работают? – Andomar

+0

Я добавил пример, который использует динамический SQL. В обоих случаях возвращается тот же SUSER_SNAME(), но в одном из них выбор завершается с ошибкой, пока он преуспевает в другом. –

1

Я думаю, вы хотите использовать 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) 
+0

У этой проблемы есть проблема с решением Andomar. См. пример, который я добавил выше. –

 Смежные вопросы

  • Нет связанных вопросов^_^