Scripting di un ruolo dell'applicazione con una password con hash


8

Devo eseguire lo scripting di un ruolo dell'applicazione con una password con hash, quindi posso copiarlo da un database a un altro.

Si consideri il seguente codice di esempio, che utilizza un ruolo applicazione per fornire un accesso elevato a un utente non attendibile:

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

Dopo aver creato la configurazione di prova in tempdb, possiamo accedere come [LimitedLogin]utente ed eseguire quanto segue:

-- login as [LimitedLogin]

USE tempdb;

SELECT *
FROM dbo.Numbers;

Viene restituito il seguente errore, come previsto:

Msg 229, Level 14, State 5, Line 1
The SELECT permission was denied on the object 'Numbers'
    , database 'Test', schema 'dbo'.

Tuttavia, una volta eseguito il sp_setapprolecon la password appropriata, possiamo vedere i risultati desiderati dalla dbo.Numberstabella:

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;

Mi piacerebbe essere in grado di automatizzare la creazione del ruolo applicativo tramite lo scripting da un database di origine da applicare a un database di destinazione. Posso facilmente eseguire la maggior parte di ciò:

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

Tuttavia, mi piacerebbe davvero poter avere la password con hash nello script, qualcosa del tipo:

CREATE APPLICATION ROLE [MyAppRole]
WITH PASSWORD = 0x12345678 HASHED
    , DEFAULT_SCHEMA = [dbo];

È possibile? Presumibilmente la versione con hash della password del ruolo dell'applicazione è memorizzata da qualche parte nel database.

Utilizzando la funzionalità "script to ->" di SQL Server Management Studio, il ruolo applicazione viene scritto con una nuova password, come:

/****** 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

Chiaramente, ciò non è utile nel mio caso, sebbene fornisca un metodo interessante per generare password casuali.


Sulla base delle risposte finora, ho creato un suggerimento Connect per aggiungere supporto per questo al prodotto:

Risposte:


6

È possibile connettersi utilizzando il DAC ( Dedicated Administrator Connection ) ed estrarre la passwordcolonna sys.sysowners. Innanzitutto, connettiti utilizzando:

ADMIN:Server\Instance

Poi:

SELECT password_hash = [password]
  FROM sys.sysowners
  WHERE name = N'MyAppRole';

Questa vista è visibile solo quando si utilizza il DAC e la colonna non è esposta nella vista padre che è visibile ( sys.database_principals). Si prega di fare attenzione con il DAC, ovviamente.

Detto questo, questo non ti aiuta. CREATE APPLICATION ROLEè molto diverso da CREATE LOGIN, in quanto non è possibile fornire una password con hash , solo testo normale. E non pensare nemmeno al reverse engineering del valore con hash, perché le versioni moderne di SQL Server utilizzano metodi elaborati per crittografare una password. Infatti se provi questo da solo vedrai che ogni volta viene creato un hash diverso, anche nella stessa affermazione:

SELECT PWDENCRYPT(N'foo'), PWDENCRYPT(N'foo');

Risultati (sulla mia macchina, questa volta), notando che i tuoi varieranno:

0x0200185968C35F22AF70...   0x0200D6C77A1D84A8467F...

Quindi, consiglierei uno dei due:

  1. Memorizzare la password dell'applicazione nel controllo del codice sorgente da qualche parte o ovunque si memorizzino altre password di sistema attualmente e utilizzarla per generare lo script per distribuire i ruoli dell'app su un altro server (o controllare l'intero codice sorgente dello CREATE APPLICATION ROLEscript); o,
  2. Utilizzo di ruoli regolari anziché ruoli applicazione.

1

Non c'è nulla nella sintassi che lo rende possibile

CREATE APPLICATION ROLE(Transact-SQL) - Libri in linea

Puoi aggirare questo problema creando l'approle in un database modello e facendo in modo che lo script lo ripristini. Un'implementazione (Dynamics NAV) crea un apprile nel codice e memorizza la password del ruolo dell'applicazione crittografata in una tabella nel database, rendendo il client la decrittografia della password del ruolo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.