sql >> Base de Datos >  >> RDS >> Sqlserver

Comprensión de la función de seguridad de SQL Server HAS_Permis_BY_Name y sus casos de USO

Hay varias instancias en las que queremos verificar el permiso en un asegurable para un principal. Antes de continuar, veamos qué son principales, asegurables y permisos.

Según la documentación de Microsoft,

  1. Asegurables en el contexto de SQL Server son recursos específicos a los que el sistema de autorización del Motor de base de datos de SQL Server controla el acceso. Se dividen en tres categorías:servidor, base de datos y esquema. En general, cualquier objeto de SQL Server o base de datos puede ser asegurable.
  2. Permisos son controles mediante los cuales asignamos, otorgamos o denegamos cierto nivel de acceso a un asegurable.
  3. Director es una entidad que recibe permiso para un asegurable. Los principales más comunes son los inicios de sesión y los usuarios de la base de datos.

SQL Server tiene una función de seguridad integrada HAS_Permis_BY_Name eso nos ayudará a saber si un principal identificado tiene un permiso específico en un asegurable determinado o no. Esta función del sistema devuelve 1 si se asigna un permiso efectivo a ese principal en un asegurable determinado y devuelve 0 si no se asigna un permiso efectivo. Obtendrá el valor NULL si el permiso efectivo o la clase protegible no son válidos.

La función del sistema HAS_Permis_BY_Name también es muy útil para verificar el permiso para su inicio de sesión. En este artículo, le mostraré un proceso paso a paso para verificar un permiso específico en un asegurable para mi director y otros directores.

La sintaxis T-SQL de esta función del sistema es la siguiente:

--T-SQL syntax
HAS_PERMS_BY_NAME (securable, securable_class, permission)
   

Se necesitarán tres parámetros obligatorios para ejecutar esta función de seguridad del sistema SQL Server.

  • Ingrese el nombre del asegurable sobre el que desea comprobar el permiso. Si un asegurable es un servidor en sí mismo, debe usar NULL.
  • El segundo parámetro es clase_segura que es el nombre de la clase. Si no está seguro, puede usar otra función del sistema sys.fn_builtin_permissions para obtener la lista completa de clases protegibles y sus permisos disponibles.
  • El tercer parámetro es el permiso donde debe ingresar el permiso efectivo sobre el cual desea verificar el asegurable especificado.

Ahora, permítame mostrarle todas las clases asegurables disponibles ejecutando la función del sistema sys.fn_builtin_permissions. He usado DISTINCT para mostrar filas por clase asegurable.

--Display all securable_class
SELECT distinct class_desc FROM sys.fn_builtin_permissions(default)

Aquí puede obtener una lista de la clase asegurable.

Si desea verificar todos los permisos posibles para cualquier clase asegurable, también puede usar esta función del sistema. Ejecute la siguiente instrucción T-SQL:

--Display each permission for all securable class
SELECT class_desc,permission_name FROM sys.fn_builtin_permissions(default);

Podemos ver la lista en la siguiente imagen. El class_desc es una clase asegurable y permission_name es un tipo de permiso. Si no está seguro acerca de la clase asegurable y los permisos que deben verificarse para cualquier asegurable, puede usar esta función del sistema.

HAS_Permis_BY_Name Casos de USO

Le mostraré 5 casos de uso de verificación de varios permisos para mi propio inicio de sesión en la instancia de SQL Server y para un inicio de sesión adicional llamado manvendra .

  1. Verifique los permisos de nivel de servidor o instancia
  2. Verificar permisos de nivel de base de datos
  3. Comprobar los permisos de nivel de objeto
  4. Verificar permisos de inicio de sesión
  5. Verificar otros permisos como catálogo de texto completo, esquema, etc.

Comencemos con el primer caso de uso para comprobar los permisos a nivel de instancia.

CASO DE USO 1:Comprobar SQL Server o permiso de nivel de instancia

Este caso de uso mostrará cómo verificar varios permisos para un servidor principal\inicio de sesión. Puede ejecutar la instrucción T-SQL anterior mediante la función del sistema sys.fn_builtin_permissions. Puede usar la cláusula WHERE en esta función para enumerar solo los permisos de nivel de servidor. Aquí, le mostraré los permisos para mi propio inicio de sesión conectado.

  • Ver estado del servidor
  • Crear rol de servidor
  • Conectar cualquier base de datos

Si está buscando algún permiso a nivel de servidor, siempre debe pasar NULL como argumento asegurable. En este ejemplo, NULL será asegurable como su nivel de servidor y los nombres de permiso anteriores tendrán un argumento de permiso. Ejecute la declaración T-SQL a continuación para verificar los permisos a nivel de servidor.

--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]

La salida se muestra en la siguiente imagen. T-SQL ha devuelto 1 para todos los permisos para mi inicio de sesión. Significa que tengo permisos para las tres operaciones. Puedo ver el estado del servidor, puedo crear una función de servidor y también puedo conectarme a cualquier base de datos en este servidor o instancia.

Permítame mostrarle si un inicio de sesión llamado 'manvendra' tiene permisos para las 3 operaciones anteriores. Usaremos la declaración EXECUTE AS LOGIN T-SQL para verificar el nivel de acceso. Asegúrese de tener el permiso IMPERSONATE en ese inicio de sesión para el que está comprobando los permisos. Ejecute la misma instrucción T-SQL anterior después de la instrucción 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]

Aquí, podemos ver que el inicio de sesión 'manvendra' no tiene acceso a ninguna de estas 3 actividades en el nivel del servidor ya que su salida ha devuelto 0.

CASO DE USO 2:Comprobar permisos a nivel de base de datos

He explicado cómo verificar varios permisos para cualquier principal en el servidor o nivel de instancia en la sección anterior. Ahora, le mostraré cómo verificar varios permisos para cualquier principal en el nivel de la base de datos. Vea la siguiente declaración:

--Display each permission for securable class ‘DATABASE’
SELECT class_desc,permission_name FROM sys.fn_builtin_permissions(default)
WHERE class_desc = ‘DATABASE’

Puede ver que hay 82 permisos disponibles en el nivel de la base de datos en la siguiente captura de pantalla.

He elegido los siguientes permisos para verificar si mi inicio de sesión o un inicio de sesión adicional 'manvendra' tiene permiso para realizar estas actividades.

  • CUALQUIERA
  • CREAR tabla
  • CREAR PROCEDIMIENTO
  • INSERTAR
  • SELECCIONAR

Aquí, asegurable será el nombre de la base de datos en la que desea verificar los permisos, la clase asegurable será 'Base de datos' y el permiso serán los nombres de permisos anteriores. Ejecute la declaración T-SQL a continuación para verificar varios permisos.

--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]

La salida devolvió 1 para cada permiso. Significa que tengo permiso para realizar todas las actividades anteriores en el contexto de la base de datos actual.

Ejecute la declaración T-SQL a continuación para verificar los mismos permisos para iniciar sesión 'manvendra' en el contexto de la base de datos seleccionada actualmente.

--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]

El resultado muestra que el inicio de sesión 'manvendra' tiene permisos muy limitados en esta base de datos. Este inicio de sesión solo puede conectarse a la base de datos y el resto de los permisos no están permitidos.

Aquí, cambié el contexto de la base de datos y elegí la base de datos 'AdventureWorksDW2019-TSQL' como un argumento asegurable y ejecuté la siguiente declaración para iniciar sesión '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]

El mismo inicio de sesión 'manvendra' tiene permiso para INSERTAR y SELECCIONAR operaciones en esta base de datos 'AdventureWorks2019-TSQL'

De manera similar, podemos ejecutar la declaración T-SQL anterior para verificar el permiso de distintas bases de datos para nuestro inicio de sesión. El resultado muestra que tengo acceso a todos los permisos.

Puede continuar y verificar otros permisos a nivel de base de datos para cualquier entidad principal mediante el uso de la función de seguridad de SQL Server del sistema anterior.

CASO DE USO 3:Comprobar permisos de NIVEL DE OBJETO

Este caso de uso ilustra el uso de permisos a nivel de objeto dentro de una base de datos. Nuevamente, puede ejecutar la declaración T-SQL a continuación para enumerar todos los permisos disponibles para la clase asegurable 'OBJETO'. He usado la cláusula WHERE en la función del sistema sys.fn_builtin_permissions para mostrar la lista de permisos a nivel de objeto.

--Check all object level permissions
SELECT class_desc,permission_name FROM sys.fn_builtin_permissions(default)
WHERE class_desc ='OBJECT'

Aquí está la lista de permisos para el Objeto de clase asegurable.

Ahora, voy a verificar los permisos a continuación en un objeto específico para cualquier cuenta de inicio de sesión y ver si esa cuenta tiene acceso para realizar las operaciones a continuación.

  • INSERTAR
  • SELECCIONAR
  • ELIMINAR
  • VER DEFINICIÓN

He usado un objeto de base de datos 'dbo.dimAccount' como asegurable, OBJECT como una clase asegurable y los permisos anteriores como argumento de permiso. Ejecute las declaraciones a continuación para mostrar los detalles del permiso.

--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]

Como soy un administrador de sistemas en esta instancia, mi cuenta devuelve 1 para cualquier permiso que esté verificando en cualquier nivel. Significa que tengo permisos completos, y esto también se puede verificar ejecutando las declaraciones a continuación.

Ejecute la declaración a continuación para verificar los permisos para el inicio de sesión '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]

Podemos ver que el inicio de sesión 'manvendra' tiene acceso a los permisos INSERTAR, SELECCIONAR y ELIMINAR, pero esta cuenta no tiene permiso para VER LA DEFINICIÓN de este objeto en la base de datos 'AdventureWorksDW2019-TSQL'.

Permítanme aplicar el acceso DENY a la operación DELETE para esta cuenta 'manvendra' en el objeto 'DimAccount' en la base de datos AdventureWorksDW2019-TSQL. Puedes ver esto en la imagen de abajo.

Podemos ver que la salida indica que el inicio de sesión 'manvendra' solo tiene acceso a las declaraciones INSERT y SELECT y no tiene permiso para la declaración DELETE.

Verifique varios niveles de acceso para cualquier inicio de sesión en cualquier objeto de la base de datos utilizando la función del sistema anterior.

CASO DE USO 4:Comprobar permiso de inicio de sesión

Este caso de uso lo ayudará a comprender cómo verificar varios permisos para iniciar sesión. Puede obtener todo este tipo de detalles utilizando esta función de seguridad del sistema SQL Server HAS_PERMS_BY_NAME.

Podemos enumerar todos los permisos disponibles para un inicio de sesión específico ejecutando la declaración T-SQL a continuación.

--List all available permission for securable class ‘LOGIN’
SELECT class_desc, permission_name FROM sys.fn_builtin_permissions(default)
WHERE class_desc ='LOGIN'

A continuación se muestra la lista de nombres de permisos para la clase asegurable 'LOGIN'.

Verificaré si tengo permiso ALTERAR o VER DEFINICIÓN al iniciar sesión ejecutando las siguientes declaraciones T-SQL. He usado login sa como argumento asegurable, LOGIN como argumento de clase asegurable y ALTER &VIEW DEFINITION como argumento de permiso en esta función del sistema.

--Check ALTER & VIEW DEFINITION permission on securable sa
SELECT HAS_PERMS_BY_NAME('sa', 'LOGIN', 'ALTER'),
HAS_PERMS_BY_NAME('sa', 'LOGIN', 'VIEW DEFINITION')

Como administrador de sistemas, tendré estos niveles de acceso, y la salida también se valida devolviendo su valor como 1.

Verifiquemos si el inicio de sesión 'manvendra' tiene permiso para ALTERAR o VER la definición del inicio de sesión 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')

La salida devolvió cero (0), lo que significa que el inicio de sesión 'manvendra' no tiene permiso para ALTERAR o VER DEFINICIÓN inicio de sesión sa.

Utilice esta función del sistema para verificar y comprender los niveles de acceso para varios inicios de sesión.

CASO DE USO 5:Comprobar otros permisos

Aquí, cubriré algunas otras clases asegurables como SCHEMA y FULLTEXT CATALOG, ENDPOINT, DISPONIBILITY GROUP, etc.

Primero enumeremos todos los permisos disponibles para la clase asegurable SCHEMA y FULLTEXT CATALOG ejecutando la siguiente instrucción:

--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'

El siguiente paso es identificar qué permiso estamos buscando para verificar nuestro principal. Voy a verificar los permisos DELETE y ALTER para la clase asegurable SCHEMA y el permiso ALTER y VIEW DEFINITION en la clase asegurable FULLTEXT CATALOG.

Necesitamos pasar sus respectivos asegurables como he pasado dbo para la clase asegurable SCHEMA y FTCatalog para la clase asegurable FULLTEXT CATALOG en la siguiente declaración.

Ejecute la declaración T-SQL a continuación para obtener permiso para su inicio de sesión.

--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]

El siguiente resultado muestra que el inicio de sesión 'manvendra' tiene acceso solo a la eliminación de SCHEMA y el resto de los accesos han sido denegados o revocados.

Conclusión

He explicado el proceso paso a paso para verificar varios permisos para múltiples clases asegurables para cualquier principal en este artículo. También puede usar esta función de seguridad de SQL Server del sistema para cumplir con los requisitos de verificación de permisos. Comparta este artículo y dé su opinión en la sección de comentarios para que podamos mejorar.