Има няколко случая, когато искаме да проверим разрешението за защитен обект за принципал. Преди да продължим, нека видим какво представляват принципал, защитени и разрешения.
Според документацията на Microsoft,
- Защитими в контекста на SQL Server са специфични ресурси, до които системата за оторизация на SQL Server Database Engine контролира достъпа. Те са разделени на три категории:сървър, база данни и схема. По принцип всеки SQL Server или обекти на база данни могат да бъдат защитени.
- Разрешения са контроли, с помощта на които предоставяме или отказваме определено ниво на достъп до защитено.
- Директор е субект, който получава разрешение за защитен обект. Най-често срещаните принципали са потребители за влизане и база данни.
SQL Server има вградена функция за защита HAS_Permis_BY_Name това ще ни помогне да разберем дали идентифицираният принципал има конкретно разрешение за даден защитен обект или не. Тази системна функция връща 1, ако ефективно разрешение е присвоено на този принципал за даден защитен обект, и връща 0, ако ефективно разрешение не е присвоено. Ще получите стойността NULL, ако ефективното разрешение или защитен клас не е валиден.
Системната функция HAS_Permis_BY_Name също е много полезна при проверка на разрешението за вашето влизане. Ще ви покажа стъпка по стъпка процес за проверка на конкретно разрешение за защитено за моя принципал и други принципали в тази статия.
Синтаксисът на T-SQL на тази системна функция е както следва:
--T-SQL syntax
HAS_PERMS_BY_NAME (securable, securable_class, permission)
Ще са необходими три задължителни параметъра, за да се изпълни тази функция за сигурност на SQL Server на системата.
- Въведете името на защитен за което искате да проверите разрешението. Ако защитеният е самият сървър, трябва да използвате NULL.
- Вторият параметър е securable_class което е името на класа. Ако не сте сигурни, можете да използвате друга системна функция sys.fn_builtin_permissions, за да получите пълния списък с защитени класове и техните налични разрешения.
- Трети параметър е разрешението където трябва да въведете ефективното разрешение, за което искате да проверите на посочения защитен обект.
Сега нека ви покажа всички налични защитени класове, като стартирам системната функция sys.fn_builtin_permissions. Използвах DISTINCT за показване на редове за защитен клас.
--Display all securable_class
SELECT distinct class_desc FROM sys.fn_builtin_permissions(default)
Тук можете да получите списък на защитения клас.
Ако искате да проверите всички възможни разрешения за всеки защитен клас, можете също да използвате тази системна функция. Изпълнете следния T-SQL оператор:
--Display each permission for all securable class
SELECT class_desc,permission_name FROM sys.fn_builtin_permissions(default);
Можем да видим списъка на изображението по-долу. class_desc е защитен клас и име_на_разрешение е вид разрешение. Ако не сте сигурни за защитения клас и разрешенията, които трябва да бъдат проверени за защитени, можете да използвате тази системна функция.
HAS_Permis_BY_Name USE Cases
Ще ви покажа 5 случая на използване на проверка на различни разрешения за моето собствено влизане в екземпляр на SQL Server и за допълнително влизане с име manvendra .
- Проверете разрешенията на ниво сървър или инстанция
- Проверете разрешенията на ниво база данни
- Проверете разрешенията на ниво обект
- Проверете разрешенията за влизане
- Проверете други разрешения като Пълен текстов каталог, Схема и др.
Нека започнем с първия случай на използване, за да проверим разрешенията на ниво екземпляр.
ИЗПОЛЗВАЙТЕ СЛУЧАЙ 1:Проверете разрешението на SQL сървър или ниво на инстанция
Този случай на използване ще покаже как да проверите различни разрешения за принципал\вход на сървър. Можете да изпълните горния израз на T-SQL, като използвате системната функция sys.fn_builtin_permissions. Можете да използвате клаузата WHERE в тази функция, за да изброите само разрешенията на ниво сървър. Тук ще ви покажа разрешенията за моето собствено свързано влизане.
- Преглед на състоянието на сървъра
- Създаване на роля на сървъра
- Свържете всяка база данни
Ако търсите разрешение на ниво сървър, винаги трябва да предавате NULL като защитен аргумент. В този пример NULL ще бъде защитено като ниво на сървъра и горните имена на разрешения ще имат аргумент за разрешение. Изпълнете по-долу T-SQL оператор, за да проверите разрешенията на ниво сървър.
--Display server level permission for your own login using which you have established the database connection
SELECT HAS_PERMS_BY_NAME(null, null, 'VIEW SERVER STATE') AS [VIEW SERVER STATE],
HAS_PERMS_BY_NAME(null, null, 'CREATE SERVER ROLE') AS [CREATE SERVER ROLE],
HAS_PERMS_BY_NAME(null, null, 'CONNECT ANY DATABASE') AS [CONNECT ANY DATABASE]
Резултатът е показан на изображението по-долу. T-SQL върна 1 за всички разрешения за моето влизане. Това означава, че имам разрешения и за трите операции. Мога да преглеждам състоянието на сървъра, мога да създам роля на сървър и също така мога да се свържа с всяка база данни на този сървър или екземпляр.
Нека ви покажа дали вход с име „manvendra“ има разрешения за горните 3 операции. Ще използваме оператора EXECUTE AS LOGIN T-SQL, за да проверим нивото на достъп. Уверете се, че имате разрешение IMPERSONATE за това влизане, за което проверявате разрешенията. Изпълнете същия T-SQL оператор, както по-горе, след израза EXECUTE AS LOGIN.
--Display server level permission for another login ‘manvendra’
EXECUTE AS LOGIN = ‘manvendra’
GO
SELECT HAS_PERMS_BY_NAME(null, null, 'VIEW SERVER STATE') AS [VIEW SERVER STATE],
HAS_PERMS_BY_NAME(null, null, 'CREATE SERVER ROLE') AS [CREATE SERVER ROLE],
HAS_PERMS_BY_NAME(null, null, 'CONNECT ANY DATABASE') AS [CONNECT ANY DATABASE]
Тук можем да видим, че входът „manvendra“ няма достъп до нито една от тези 3 дейности на ниво сървър, тъй като изходът им е върнал 0.
ИЗПОЛЗВАЙТЕ СЛУЧАЙ 2:Проверете разрешенията на ниво база данни
Обясних как да проверявам различни разрешения за всеки принципал на ниво сървър или инстанция в горния раздел. Сега ще ви покажа как да проверявате различни разрешения за всеки принципал на ниво база данни. Вижте изявлението по-долу:
--Display each permission for securable class ‘DATABASE’
SELECT class_desc,permission_name FROM sys.fn_builtin_permissions(default)
WHERE class_desc = ‘DATABASE’
Можете да видите, че има 82 разрешения на ниво база данни на екранната снимка по-долу.
Избрах разрешенията по-долу, за да проверя дали моето име за влизане или допълнителен вход „manvendra“ има разрешение за извършване на тези дейности.
- ВСЕКИ
- СЪЗДАВАЙТЕ таблица
- СЪЗДАВАНЕ НА ПРОЦЕДУРА
- ВМЪКНЕТЕ
- ИЗБЕРЕТЕ
Тук защитено ще бъде името на базата данни, за което искате да проверите разрешенията, защитеният клас ще бъде „База данни“, а разрешението ще бъде горните имена на разрешения. Изпълнете по-долу T-SQL оператор, за да проверите различни разрешения.
--Display few specific permissions for your own connected login on a DATABASE
SELECT HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'ANY') AS [DB Access],
HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'CREATE TABLE') AS [CREATE TABLE],
HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'CREATE PROCEDURE') AS [CREATE PROCEDURE],
HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'INSERT') AS [INSERT Access],
HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'SELECT') AS [SELECT Access]
Резултатът върна 1 за всяко разрешение. Това означава, че имам разрешение да извършвам всички горепосочени дейности в контекста на текущата база данни.
Изпълнете по-долу T-SQL оператор, за да проверите същите разрешения за влизане „manvendra“ в текущо избрания контекст на базата данни.
--Display few specific permissions for login ‘manvendra’ on current database
EXECUTE AS LOGIN ='manvendra'
GO
SELECT HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'ANY') AS [DB Access],
HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'CREATE TABLE') AS [CREATE TABLE],
HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'CREATE PROCEDURE') AS [CREATE PROCEDURE],
HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'INSERT') AS [INSERT Access],
HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'SELECT') AS [SELECT Access]
Резултатът показва, че входът „manvendra“ има много ограничени разрешения за тази база данни. Това влизане може да се свърже само с базата данни, а останалите разрешения не са разрешени.
Тук промених контекста на базата данни и избрах база данни „AdventureWorksDW2019-TSQL“ като защитен аргумент и изпълних изявлението по-долу за вход „manvendra“.
--Display few specific permissions for login ‘manvendra’ on database ‘AdventureWorksDW2019-TSQL’
EXECUTE AS LOGIN ='manvendra'
GO
SELECT HAS_PERMS_BY_NAME('AdventureWorksDW2019-TSQL', 'DATABASE', 'ANY') AS [DB Access],
HAS_PERMS_BY_NAME('AdventureWorksDW2019-TSQL', 'DATABASE', 'CREATE TABLE') AS [CREATE TABLE],
HAS_PERMS_BY_NAME('AdventureWorksDW2019-TSQL', 'DATABASE', 'CREATE PROCEDURE') AS [CREATE PROCEDURE],
HAS_PERMS_BY_NAME('AdventureWorksDW2019-TSQL', 'DATABASE', 'INSERT') AS [INSERT Access],
HAS_PERMS_BY_NAME('AdventureWorksDW2019-TSQL', 'DATABASE', 'SELECT') AS [SELECT Access]
Същият вход „manvendra“ има разрешение за INSERT и SELECT операции в тази база данни „AdventureWorks2019-TSQL“
По подобен начин можем да изпълним горния израз на T-SQL, за да проверим разрешението за отделни бази данни за нашето влизане. Резултатът показва, че имам достъп до всички разрешения.
Можете да продължите и да проверите друго разрешение на ниво база данни за всеки принципал, като използвате горната функция за сигурност на SQL Server на системата.
ИЗПОЛЗВАТЕ СЛУЧАЙ 3:Проверете разрешенията на ОБЕКТ-НИВО
Този случай на употреба илюстрира използването на разрешения на ниво обект в рамките на база данни. Отново можете да изпълните по-долу T-SQL оператор, за да изброите всички налични разрешения за защитения клас „OBJECT“. Използвах клаузата WHERE в системната функция sys.fn_builtin_permissions за показване на списъка с разрешения на ниво обект.
--Check all object level permissions
SELECT class_desc,permission_name FROM sys.fn_builtin_permissions(default)
WHERE class_desc ='OBJECT'
Ето списъка с разрешения за защитения клас Object.
Сега ще проверя разрешенията по-долу за конкретен обект за всеки акаунт за влизане и ще видя дали този акаунт има достъп за извършване на операциите по-долу.
- ВМЪКНЕТЕ
- ИЗБЕРЕТЕ
- ИЗТРИВАНЕ
- ПРЕГЛЕД ДЕФИНИЦИЯ
Използвах обект на база данни „dbo.dimAccount“ като защитен, OBJECT като защитен клас и горните разрешения като аргумент за разрешение. Изпълнете следните оператори, за да покажете подробностите за разрешението.
--Check some specific object level permissions for your own login
SELECT HAS_PERMS_BY_NAME('[dbo].[DimAccount]', 'OBJECT', 'INSERT') AS [Insert Permission],
HAS_PERMS_BY_NAME('[dbo].[DimAccount]', 'OBJECT', 'SELECT') AS [Select Permission],
HAS_PERMS_BY_NAME('[dbo].[DimAccount]', 'OBJECT', 'DELETE') AS [DELETE Permission],
HAS_PERMS_BY_NAME('[dbo].[DimAccount]', 'OBJECT', 'VIEW DEFINITION') AS [VIEW DEFINITION Access]
Тъй като аз съм системен администратор на този екземпляр, акаунтът ми връща 1 за всяко разрешение, което проверявам на всяко ниво. Това означава, че имам пълни разрешения и това може да се провери, като изпълните и следните оператори.
Изпълнете оператора по-долу, за да проверите разрешенията за влизане „manvendra“.
--Check some specific object level permissions for another login ‘manvendra’
EXECUTE AS USER ='manvendra'
GO
USE [AdventureWorksDW2019-TSQL]
GO
SELECT HAS_PERMS_BY_NAME('[dbo].[DimAccount]', 'OBJECT', 'INSERT') AS [Insert Permission],
HAS_PERMS_BY_NAME('[dbo].[DimAccount]', 'OBJECT', 'SELECT') AS [Select Permission],
HAS_PERMS_BY_NAME('[dbo].[DimAccount]', 'OBJECT', 'DELETE') AS [DELETE Permission],
HAS_PERMS_BY_NAME('[dbo].[DimAccount]', 'OBJECT', 'VIEW DEFINITION') AS [VIEW DEFINITION Access]
Можем да видим, че входът „manvendra“ има достъп до разрешенията INSERT, SELECT и DELETE, но този акаунт няма разрешение за ПРЕГЛЕД НА ДЕФИНИЦИЯТА на този обект в базата данни „AdventureWorksDW2019-TSQL“.
Позволете ми да приложа ОТКАЗВАНЕ на достъп до операцията ИЗТРИВАНЕ за този акаунт „manvendra“ върху обект „DimAccount“ в базата данни AdventureWorksDW2019-TSQL. Можете да видите това на изображението по-долу.
Можем да видим, че изходът показва, че входът „manvendra“ има достъп само до операторите INSERT и SELECT и няма разрешение за оператора DELETE.
Проверете различни нива на достъп за всяко влизане в който и да е обект на база данни, като използвате горната системна функция.
ИЗПОЛЗВАНЕ СЛУЧАЙ 4:Проверете разрешението за влизане
Този случай на употреба ще ви помогне да разберете как да проверявате различни разрешения за влизане. Можете да получите всички тези видове подробности, като използвате тази системна функция за сигурност на SQL Server HAS_PERMS_BY_NAME.
Можем да изброим всички налични разрешения за конкретно влизане, като изпълним по-долу T-SQL оператор.
--List all available permission for securable class ‘LOGIN’
SELECT class_desc, permission_name FROM sys.fn_builtin_permissions(default)
WHERE class_desc ='LOGIN'
По-долу е даден списък с имена на разрешения за защитения клас „LOGIN“.
Ще проверя дали имам разрешение ALTER или VIEW DEFINITION при влизане sa, като изпълня следните T-SQL оператори. Използвах login sa като защитен аргумент, LOGIN като защитен аргумент на клас и ALTER &VIEW DEFINITION като аргумент за разрешение в тази системна функция.
--Check ALTER & VIEW DEFINITION permission on securable sa
SELECT HAS_PERMS_BY_NAME('sa', 'LOGIN', 'ALTER'),
HAS_PERMS_BY_NAME('sa', 'LOGIN', 'VIEW DEFINITION')
Като системен администратор ще имам тези нива на достъп и изходът също се потвърждава чрез връщане на стойността им като 1.
Нека проверим дали входът „manvendra“ има разрешение да ПРОМЕНЯ или ПРЕГЛЕД дефиницията на входа sa.
--Check ALTER & VIEW DEFINITION permission on securable sa for principal ‘manvendra’
EXECUTE AS USER ='manvendra'
GO
SELECT HAS_PERMS_BY_NAME('sa', 'LOGIN', 'ALTER'),
HAS_PERMS_BY_NAME('sa', 'LOGIN', 'VIEW DEFINITION')
Резултатът се връща като нула (0), което означава, че входът „manvendra“ няма разрешение за ПРОМЕНЯНЕ или ПРЕГЛЕД НА ДЕФИНИЦИЯ за влизане sa.
Използвайте тази системна функция, за да проверите и разберете нивата на достъп за различни входове.
ИЗПОЛЗВАНЕ СЛУЧАЙ 5:Проверете други разрешения
Тук ще разгледам някои други защитени класове като SCHEMA и FULLTEXT CATALOG, ENDPOINT, AVAILABILITY GROUP и др.
Нека първо изброим всички разрешения, налични за защитен клас SCHEMA и FULLTEXT CATALOG, като изпълним следния израз:
--List all available permission for securable class ‘SCHEMA’ & ‘FTCatalog’. FTCatalog is full text catalog.
SELECT class_desc, permission_name FROM sys.fn_builtin_permissions(default)
WHERE class_desc='SCHEMA' OR
class_desc= 'FULLTEXT CATALOG'
Следващата стъпка е да определим кое разрешение търсим, за да проверим за нашия принципал. Ще проверя разрешенията DELETE и ALTER за защитен клас SCHEMA и разрешението ALTER и VIEW DEFINITION в защитения клас FULLTEXT CATALOG.
Трябва да предадем съответните им защитени, както аз съм предал dbo за защитения клас SCHEMA и FTCatalog за защитен клас FULLTEXT CATALOG в изявлението по-долу.
Изпълнете по-долу T-SQL оператор, за да получите разрешение за вашето влизане.
--List below permissions for securable class ‘SCHEMA’ & ‘FTCatalog’.
SELECT HAS_PERMS_BY_NAME('dbo', 'SCHEMA', 'DELETE') AS [Schema Deletion Access],
HAS_PERMS_BY_NAME('dbo', 'SCHEMA', 'ALTER') AS [Schema Alter Access],
HAS_PERMS_BY_NAME('[FTCatalog]', 'FULLTEXT CATALOG', 'ALTER') AS [FTC Alter Access],
HAS_PERMS_BY_NAME('[FTCatalog]', 'FULLTEXT CATALOG', 'VIEW DEFINITION') AS [VIEW DEFINITION]
Изходът по-долу показва, че входът „manvendra“ има достъп само до изтриване на SCHEMA, а останалите достъпи са били отказани или отменени.
Заключение
Обясних процеса стъпка по стъпка за проверка на различни разрешения за множество защитени класове за всеки принципал в тази статия. Можете също така да използвате тази системна функция за защита на SQL Server, за да изпълните изискванията си за проверка на разрешенията. Моля, споделете тази статия и дайте отзивите си в секцията за коментари, за да можем да подобрим.