Preciso criar um script para uma função de aplicativo com uma senha com hash, para copiá-la de um banco de dados para outro.
Considere o seguinte código de exemplo, que usa uma Função de Aplicativo para fornecer acesso elevado a um usuário não confiável:
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
Depois de criar a configuração de teste no tempdb, podemos fazer login como [LimitedLogin]
usuário e executar o seguinte:
-- login as [LimitedLogin]
USE tempdb;
SELECT *
FROM dbo.Numbers;
O seguinte erro é retornado, conforme o esperado:
Msg 229, Level 14, State 5, Line 1
The SELECT permission was denied on the object 'Numbers'
, database 'Test', schema 'dbo'.
No entanto, uma vez executada a sp_setapprole
senha apropriada, podemos ver os resultados desejados da dbo.Numbers
tabela:
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;
Eu gostaria de poder automatizar a criação da Função de Aplicativo criando um script de um banco de dados de origem para ser aplicado a um banco de dados de destino. Eu posso facilmente executar a maioria disso:
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';
No entanto, eu realmente gostaria de poder ter a senha com hash no script, algo como:
CREATE APPLICATION ROLE [MyAppRole]
WITH PASSWORD = 0x12345678 HASHED
, DEFAULT_SCHEMA = [dbo];
Isso é possível? Presumivelmente, a versão em hash da senha da função de aplicativo está armazenada em algum lugar do banco de dados.
Usando a funcionalidade "script para ->" do SQL Server Management Studio, a Função do Aplicativo é escrita com uma nova senha, 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, isso não é útil no meu caso, embora ele forneça um método interessante de gerar senhas aleatórias.
Com base nas respostas até agora, criei uma sugestão do Connect para adicionar suporte para isso no produto: