Necesito escribir una función de aplicación con una contraseña hash, para poder copiarla de una base de datos a otra.
Considere el siguiente código de ejemplo, que usa un Rol de aplicación para proporcionar acceso elevado a un usuario no confiable:
USE tempdb;
CREATE LOGIN LimitedLogin
WITH PASSWORD = 'Password1'
, CHECK_POLICY = OFF
, CHECK_EXPIRATION = OFF;
CREATE USER LimitedLogin
FOR LOGIN LimitedLogin
WITH DEFAULT_SCHEMA = dbo;
CREATE APPLICATION ROLE MyAppRole
WITH PASSWORD = 'Password2'
, DEFAULT_SCHEMA = dbo;
EXEC sp_addrolemember @rolename = 'db_datareader'
, @membername = 'MyAppRole';
CREATE TABLE dbo.Numbers
(
[Number] int CONSTRAINT PK_Numbers
PRIMARY KEY CLUSTERED
IDENTITY(1,1) NOT NULL
);
INSERT INTO dbo.Numbers
VALUES (1)
, (2);
GO
Una vez que creamos la configuración de prueba en tempdb, podemos iniciar sesión como [LimitedLogin]
usuario y ejecutar lo siguiente:
-- login as [LimitedLogin]
USE tempdb;
SELECT *
FROM dbo.Numbers;
Se devuelve el siguiente error, como se esperaba:
Msg 229, Level 14, State 5, Line 1
The SELECT permission was denied on the object 'Numbers'
, database 'Test', schema 'dbo'.
Sin embargo, una vez que ejecutamos sp_setapprole
con la contraseña apropiada, podemos ver los resultados deseados de la dbo.Numbers
tabla:
DECLARE @cookie VARBINARY(8000);
EXEC sp_setapprole @rolename = 'MyAppRole'
, @password = 'Password2'
, @fCreateCookie = 1
, @cookie = @cookie OUT;
SELECT @cookie;
SELECT TOP(10) *
FROM dbo.Numbers;
EXEC sp_unsetapprole @cookie = @cookie;
Me gustaría poder automatizar la creación del rol de la aplicación mediante una secuencia de comandos desde una base de datos de origen para aplicarla a una base de datos de destino. Puedo realizar la mayoría de eso fácilmente al:
SELECT 'CREATE APPLICATION ROLE ' + QUOTENAME(dp.name) + '
WITH PASSWORD = ''xxxx''
, DEFAULT_SCHEMA = ' + QUOTENAME(dp.default_schema_name) + ';'
FROM sys.database_principals dp
WHERE dp.type_desc = 'APPLICATION_ROLE';
Sin embargo, realmente me gustaría poder tener la contraseña hash en el script, algo así como:
CREATE APPLICATION ROLE [MyAppRole]
WITH PASSWORD = 0x12345678 HASHED
, DEFAULT_SCHEMA = [dbo];
es posible? Presumiblemente, la versión hash de la contraseña del rol de la aplicación se almacena en algún lugar de la base de datos.
Usando la funcionalidad "script to ->" de SQL Server Management Studio, el rol de la aplicación se escribe con una nueva contraseña, como:
/****** Object: ApplicationRole [MyAppRole] Script Date: 9/22/2015 10:18:12 AM ******/
/* To avoid disclosure of passwords, the password is generated in script. */
declare @idx as int
declare @randomPwd as nvarchar(64)
declare @rnd as float
select @idx = 0
select @randomPwd = N''
select @rnd = rand((@@CPU_BUSY % 100) + ((@@IDLE % 100) * 100) +
(DATEPART(ss, GETDATE()) * 10000) + ((cast(DATEPART(ms, GETDATE()) as int) % 100) * 1000000))
while @idx < 64
begin
select @randomPwd = @randomPwd + char((cast((@rnd * 83) as int) + 43))
select @idx = @idx + 1
select @rnd = rand()
end
declare @statement nvarchar(4000)
select @statement = N'CREATE APPLICATION ROLE [MyAppRole] WITH DEFAULT_SCHEMA = [dbo], ' + N'PASSWORD = N' + QUOTENAME(@randomPwd,'''')
EXEC dbo.sp_executesql @statement
GO
Claramente, eso no es útil en mi caso, aunque proporciona un método interesante para generar contraseñas aleatorias.
Basado en las respuestas hasta ahora, he creado una sugerencia de Connect para agregar soporte para esto al producto: