Firma de módulos

Nuevo: 5 de diciembre de 2005

Las aplicaciones de bases de datos requieren a menudo que el acceso a las tablas y objetos subyacentes en el esquema de la aplicación pueda controlarse a través de procedimientos o vistas de nivel básico. El objetivo es conceder acceso a los usuarios finales de los objetos de nivel básico, que podrán, de esta manera, tener acceso a los objetos subyacentes en nombre del usuario. De esta forma, no se tiene que conceder acceso a los usuarios finales a todos los objetos del esquema de la aplicación. Este método cumple dos fines:

  • Simplifica la administración de permisos, de modo que sólo es necesario administrar los permisos de un subconjunto más pequeño de objetos, en lugar de hacerlo con todos los objetos del esquema de la aplicación.
  • Es posible ocultar el diseño del esquema subyacente al usuario final, dado que sólo se exponen los puntos de entrada.

Microsoft SQL Server tiene unas características que ayudan a conseguir estos escenarios; por ejemplo, el encadenamiento de propiedad y el uso de la instrucción EXECUTE AS. SQL Server 2005 también incorpora la capacidad de firmar módulos en la base de datos. La firma de módulos ofrece capacidades similares, pero no cambia el contexto de ejecución. Un módulo en este contexto hace referencia a un procedimiento almacenado, una función, un desencadenador o un ensamblado. Para obtener más información, vea Cadenas de propiedad, Usar EXECUTE AS para crear conjuntos de permisos personalizados y el Tutorial de seguridad, Firmar procedimientos almacenados con un certificado

Firmas de módulos

SQL Server 2005 incorpora la capacidad de firmar módulos en la base de datos como, por ejemplo, procedimientos almacenados, funciones, desencadenadores o ensamblados. Tenga en cuenta que no se pueden firmar los desencadenadores del lenguaje de definición de datos (DDL). Una firma digital es un resumen de datos cifrados con una clave privada del firmante. La clave privada garantiza que la firma digital sea única para su portador o propietario.

Para firmar datos, el firmante resume los datos, los cifra con una clave privada y adjunta el valor resumido y cifrado a los datos. Para verificar la firma, el comprobador utiliza la clave pública del firmante para descifrar el valor resumido y cifrado que se adjunta a los datos. A continuación, el comprobador compara el valor resumido y descifrado con el valor resumido que se ha calculado en los datos complementarios. Es importante que tanto el firmante como el comprobador usen la misma función hash para resumir los datos.

ms345102.Caution(es-es,SQL.90).gifAdvertencia:
La firma de módulos sólo se debe utilizar para conceder permisos, nunca para denegarlos o revocarlos.

Escenario

Suponga que el acceso a la vista sys.sysprocesses debe controlarse a través del procedimiento almacenado usp_sysprocesses. Los usuarios sólo pueden tener acceso a la información de sys.sysprocesses cuando pasan por el procedimiento usp_sysprocesses. Dado que los objetos de usp_sysprocesses y sys.sysprocesses tienen diferentes propietarios, no se aplica el encadenamiento de propiedad.

Primero, se debe crear un certificado en el servidor a partir de un par de claves, utilizando la instrucción CREATE CERTIFICATE. A continuación, se debe conceder al certificado los permisos para realizar selecciones en la tabla sys.sysprocesses. No obstante, debido a que SQL Server sólo concede permisos a entidades de seguridad, primero es necesario crear un inicio de sesión del certificado mediante la instrucción CREATE LOGIN. Este inicio de sesión no necesita permisos de conexión en el servidor, ya que sólo es un marcador de posición y no se utilizará para conectarse a una instancia de servidor. A continuación, se puede conceder permisos SELECT en la tabla sys.sysprocesses a este inicio de sesión asignado al certificado; esto se realiza mediante la instrucción GRANT VIEW SERVER STATE TO. Después de crear el procedimiento almacenado usp_sysprocesses, se puede firmar con el certificado (en realidad, con la clave privada que corresponde a este certificado) mediante la instrucción ADD SIGNATURE. Se crea una función y se le concede permiso de ejecución en el procedimiento almacenado usp_sysprocesses. De este modo, los usuarios miembros de esta función tendrán permiso para ejecutar el procedimiento almacenado usp_sysprocesses y, por lo tanto, realizar selecciones (SELECT) en la vista sys.sysprocess. Cuando se ejecuta un módulo firmado, los permisos concedidos a la entidad de seguridad (mediante el uso de la instrucción GRANT) asociados al certificado firmado se unen temporalmente (mediante la instrucción UNION) al testigo de seguridad mientras dura la llamada. Estos permisos se eliminan del testigo de seguridad tan pronto como vuelve el control de ejecución. Por lo tanto, se dispone de forma efectiva de un conjunto adicional de permisos sólo durante la ejecución del módulo. Cualquier otro usuario o función a los que se concede permisos EXECUTE en este procedimiento también tendrán las mismas capacidades.

Ejemplo

La siguiente secuencia de comandos Transact-SQL proporciona un ejemplo del escenario descrito anteriormente. Se crea un certificado a partir de un par de claves y se asigna a un nuevo inicio de sesión. Primero se debe crear un par de claves de prueba mediante la herramienta MakeCert que se incluye con el SDK de .NET Framework. A continuación, se conceden los permisos de selección para la vista sys.sysproceses al inicio de sesión asociado al certificado. Se crea el procedimiento almacenado administrado usp_sysprocesses en la nueva base de datos y se firma con el certificado. Se crea la función SysProcRole y se le concede permisos de ejecución en el procedimiento almacenado usp_sysprocesses. Se crea un usuario de prueba y se agrega a la función SysProcRole. El usuario de prueba realiza una instrucción SELECT en sys.sysprocess y, a continuación, ejecuta el procedimiento almacenado usp_sysprocesses para comparación. Después, la secuencia de comandos limpia el entorno de prueba.

use master
go

-- Create a test database.
CREATE DATABASE db_Demo
go

-- Create a certificate on the server. A test key pair can be created
-- using the MakeCert tool that ships with the .NET Framework SDK.
CREATE CERTIFICATE SysProcCert FROM FILE = 'e:\programming\testCert.cer'
go

-- Create a login and map it to the certificate.
CREATE LOGIN login_SysProcCert FROM CERTIFICATE SysProcCert
Go

-- Revoke the connect permission.
REVOKE CONNECT SQL FROM login_SysProcCert ;
go 
 
-- Grant the certificate, through the login, permission to select from sys.sysprocesses view.
GRANT VIEW SERVER STATE TO login_SysProcCert
go

-- Create a test login.
CREATE LOGIN bob WITH PASSWORD = '!axLe1432ciosILD98'
go

-- Connect to the test database.
use db_Demo
go

-- Create the master key for the test database (used to protect 
-- private keys and certificates in the database).
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Iullsku409So!22BZo' 

-- Create a certificate from a private key.
CREATE CERTIFICATE SysProcCert FROM FILE = 'e:\programming\testCert.cer'
WITH PRIVATE KEY
(FILE = 'e:\programming\testCert.pvk', 
 DECRYPTION BY PASSWORD= '0sJiy3569L!ns!ko12AeDDf', 
 ENCRYPTION BY PASSWORD='0Jiw43!!no92j1joksi')
go 

-- Create the assembly on the server. The assembly DLL must be signed.
CREATE ASSEMBLY SysStoredProcedures
FROM 'E:\programming\SysStoredProcs.dll'
WITH PERMISSION_SET = SAFE
go 

-- Create the managed stored procedure on the server.
CREATE PROCEDURE usp_sysprocesses
AS EXTERNAL NAME SysStoredProcedures.StoredProcedures.usp_sysprocesses
go 

-- Add the signature to the stored procedure.
ADD SIGNATURE TO [dbo].[usp_sysprocesses] 
BY CERTIFICATE SysProcCert WITH PASSWORD = '0Jiw43!!no92j1joksi'
go 

-- Create a role.
CREATE ROLE SysProcRole
go

-- Create a test user
CREATE USER bob
go

-- Add the test user to the role.
EXEC sp_addrolemember 'SysProcRole', 'bob'
go

-- Grant execute permissions on the stored procedure to the new role.
GRANT EXECUTE ON [dbo].[usp_sysprocesses] TO SysProcRole
go
 
-- Connect as the test user.
EXECUTE AS LOGIN = 'bob'
use db_Demo
go
 
-- User only has permission to see their own processes.
SELECT * FROM sys.sysprocesses
go

-- Execute the stored procedure, which has been signed.
exec usp_sysprocesses
go

-- REVERT
REVERT
----------------------------------------------------------------------
-- Cleanup

use db_Demo
go

use master
go

DROP DATABASE db_Demo
go 

DROP login login_SysProcCert
DROP login bob
go

DROP CERTIFICATE SysProcCert
go

A continuación se muestra el código fuente para el procedimiento almacenado usp_sysprocesses, que realiza una instrucción SELECT en la vista sys.sysprocesses. El ensamblado debe firmarse cuando se genera.

C#

using System;
using System.Data.SqlClient;
using Microsoft.SqlServer.Server;

public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void usp_sysprocesses()
{
    using(SqlConnection connection = new SqlConnection("context connection=true"))
    {
        connection.Open();
        SqlCommand command = new SqlCommand("SELECT * FROM sys.sysprocesses", connection);
        SqlContext.Pipe.ExecuteAndSend(command);
    }
}
};

Visual Basic

Imports System
Imports System.Data.SqlClient
Imports Microsoft.SqlServer.Server

Partial Public Class StoredProcedures
<Microsoft.SqlServer.Server.SqlProcedure()> _
Public Shared Sub  usp_sysprocesses ()
    Using connection As New SqlConnection("context connection=true")
        connection.Open()

        Dim command As New SqlCommand("SELECT * FROM sys.sysprocesses", connection)
        SqlContext.Pipe.ExecuteAndSend(command)
    End Using
End Sub
End Class

Vea también

Otros recursos

CREATE CERTIFICATE (Transact-SQL)
CREATE LOGIN (Transact-SQL)
GRANT (Transact-SQL)
CREATE MASTER KEY (Transact-SQL)
ADD SIGNATURE (Transact-SQL)
CREATE ROLE (Transact-SQL)

Ayuda e información

Obtener ayuda sobre SQL Server 2005