2010-09-28 24 views
32

Tengo una base de datos de SQL Server 2008 donde todo el acceso a las tablas subyacentes se realiza a través de procedimientos almacenados. Algunos procedimientos almacenados simplemente SELECCIONAN registros de las tablas mientras que otros ACTUALIZAN, INSERTAN y ELIMINAN.Procedimiento almacenado y permisos: ¿es suficiente EJECUTAR?

Si un procedimiento almacenado ACTUALIZA una tabla, ¿el usuario que ejecuta el procedimiento almacenado también necesita permisos de ACTUALIZACIÓN para las tablas afectadas o es el hecho de que tienen permisos de EJECUTAR el procedimiento almacenado lo suficiente?

Básicamente me pregunto si dar al usuario permisos de EJECUTAR a los procedimientos almacenados es suficiente o si tengo que darles SELECCIONAR, ACTUALIZAR, ELIMINAR e INSERTAR permisos a las tablas para que funcionen los procedimientos almacenados. Gracias.

[EDIT] En la mayoría de mis procedimientos almacenados, de hecho parece que EXECUTE es suficiente. Sin embargo, encontré que en procedimientos almacenados donde se usaba "Execute sp_Executesql", EXECUTE no era suficiente. Las tablas involucradas deben tener permisos para las acciones que se realizan dentro de "sp_Executesql".

+3

Me temo que al usar consultas SQL dinámicas tendrá que otorgar permisos sobre el objeto subyacente. He actualizado la respuesta para reflejar eso. –

+0

@Noel - Estás en lo cierto. Descubrí que necesitaba permitir el acceso del lector de datos a las tablas para los usuarios. Afortunadamente, ese no era un problema para mi situación, ya que a todos los usuarios se les permitía ver todos los datos. – webworm

+0

En otra respuesta, @RemusRusanu vincula a una alternativa: 1) Crear un certificado; 2) Crear un usuario asociado con ese certificado; 3) Conceder a ese usuario los derechos apropiados [a los recursos protegidos]; y 4) Firme el sproc con el certificado, cada vez que cambie el sproc (stackoverflow.com/a/4081604/6894566, vinculándolo a: sommarskog.se/grantperm.html#Certificates). La firma agrega los derechos de usuario del certificado al token de usuario actual, que SQL Server preserva al llamar a los procedimientos del sistema y al SQL dinámico invocado a través de EXEC() o sp_executesql. Entonces el sproc tiene éxito. – iokevins

Respuesta

11

La ejecución de permisos en el procedimiento almacenado es suficiente.

CREATE TABLE dbo.Temp(n int) 

GO 
DENY INSERT ON dbo.Temp TO <your role> 
GO 
CREATE PROCEDURE dbo.SPTemp(@Int int) 
AS 

INSERT dbo.Temp 
SELECT @Int 

GO 

GRANT EXEC ON dbo.SPTemp TO <your role> 

GO 

Entonces el (no db_owner) el usuario tendrá los siguientes derechos:

EXEC dbo.SPTemp 10 
GO 

INSERT dbo.Temp --INSERT permission was denied on the object 'Temp' 
SELECT 10 

Sin embargo, si hay SQL dinámico dentro dbo.SPTemp que intenta insertar en dbo.Temp entonces que fallará. En este caso, será necesario otorgar permiso directo sobre la mesa.

+7

Esto es al menos engañoso, si no es incorrecto. Su ejemplo solo funciona porque el propietario del procedimiento y el propietario de la tabla es el mismo, y el encadenamiento de propiedad omite la verificación de acceso. Si el propietario del procedimiento * * no es el propietario de la tabla, sino que simplemente tiene el permiso CONTROL (es decir, tiene el permiso * todo * pero no es el propietario), su ejemplo fallará. –

+1

@Remu, uno deberá ser miembro del rol db_owner para que su escenario pase. –

+0

En otra respuesta, @RemusRusanu se vincula a una alternativa: 1) Crear un certificado; 2) Crear un usuario asociado con ese certificado; 3) Conceder a ese usuario los derechos apropiados [a los recursos protegidos]; y 4) Firme el sproc con el certificado, cada vez que cambie el sproc (https://stackoverflow.com/a/4081604/6894566, vinculándolo a: http://www.sommarskog.se/grantperm.html#Certificates) . La firma agrega los derechos de usuario del certificado al token de usuario actual, que SQL Server preserva al llamar a los procedimientos del sistema y al SQL dinámico invocado a través de EXEC() o sp_executesql. Entonces el sproc tiene éxito. – iokevins

23

Los permisos en las tablas no están marcados (incluido DENY) si las tablas y el proc tienen el mismo propietario. También pueden estar en esquemas diferentes siempre que los esquemas tengan el mismo propietario.

Ver Ownership chaining en MSDN

Editar, desde un comentario de una respuesta borrado.

El contexto es siempre el inicio de sesión actual a menos que se haya utilizado EXECUTE AS: solo los permisos DML de objeto referenciados no están marcados. Pruebe OBJECT_ID (tabla de referencia) en un proceso almacenado donde no se asignan derechos a la tabla de referencias. Da NULL. Si el propietario del proceso almacenado lo ejecuta, le daría un valor porque el propietario tiene derechos en la tabla de referencia

+0

+1 por mencionar DENY –

+0

la sugerencia de 'OBJECT_ID' fue muy útil; Necesitaba una forma de verificar si un usuario puede ejecutar un procedimiento almacenado, esto funcionó maravillosamente – Simon1979

2

El permiso de ejecución en un procedimiento almacenado que hace una inserción, actualización o eliminación es suficiente. No necesita otorgar esos permisos en el nivel de la tabla. De hecho, desalentaría ese enfoque. El uso de un procedimiento almacenado le brinda más control sobre cómo se produce el cambio. Por ejemplo, es posible que desee hacer algunas comprobaciones antes de permitir la actualización. Usar un procedimiento almacenado también puede ayudar a prevenir accidentes graves, como eliminar todas las filas de la tabla porque alguien olvidó la cláusula WHERE.

0

¡MUCHAS GRACIAS! Tuve un problema similar. Esto me lleva a la respuesta.

Estaba intentando truncar una tabla en un procedimiento almacenado que llamaba a otros procedimientos almacenados que estaban anidados en las instrucciones IF.

Mi error fue

El servidor principal "dominio \ my_id" no es capaz de acceder a la base de datos "2nd_DB" bajo el contexto de seguridad actual.

yo le había dado las llamadas almacenado derechos de procedimiento para hacer el truncado (EXECUTE AS DE AUTO), que a su vez causa un problema porque el yo no tenía derechos sobre el segundo DB. Nuestra solución fue mover el truncado a otro SP, incluir el EXECUTE AS SELF. Ahora llamamos al SP truncado, ejecutamos nuestro procesamiento de datos, hacemos una determinación lógica y llamamos al 3er SP apropiado.

1

Tal vez se puede utilizar

"en ejecutar como propietario"

cuando se crea la procedure.such almacenado de la siguiente manera:

create procedure XXX 
with execute as owner 
as 
begin 
... 
end 
go 

después, sólo tendrá a conceder al usuario el permiso de ejecución para el procedimiento almacenado XXX.

+0

. Esto funcionó para mí. estaba buscando proporcionar acceso a una tabla a un usuario a través del procedimiento almacenado y funcionó. la tabla no tiene que ser propiedad del mismo esquema que el procedimiento almacenado. – gopstar

Cuestiones relacionadas