Skripting einer Anwendungsrolle mit einem Hash-Passwort

8

Ich muss eine Anwendungsrolle mit einem Hash-Kennwort skripten, damit ich sie von einer Datenbank in eine andere kopieren kann.

Betrachten Sie den folgenden Beispielcode, der eine Anwendungsrolle verwendet, um einem nicht vertrauenswürdigen Benutzer erhöhten Zugriff zu gewähren:

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

Sobald wir das Test-Setup in Tempdb erstellt haben, können wir uns als [LimitedLogin]Benutzer anmelden und Folgendes ausführen:

-- login as [LimitedLogin]

USE tempdb;

SELECT *
FROM dbo.Numbers;

Der folgende Fehler wird wie erwartet zurückgegeben:

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

Sobald wir das sp_setapprolemit dem entsprechenden Passwort ausführen , können wir die gewünschten Ergebnisse aus der dbo.NumbersTabelle sehen:

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;

Ich möchte in der Lage sein, das Erstellen der Anwendungsrolle zu automatisieren, indem ich ein Skript aus einer Quellendatenbank erhalte, das auf eine Zieldatenbank angewendet werden soll. Ich kann den größten Teil davon leicht ausführen, indem ich:

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

Ich möchte jedoch wirklich in der Lage sein, das Hash-Passwort im Skript zu haben, etwa:

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

Ist das möglich? Vermutlich ist die Hash-Version des Kennworts für die Anwendungsrolle irgendwo in der Datenbank gespeichert.

Bei Verwendung der SQL Server Management Studio-Funktion "Skript zu ->" wird die Anwendungsrolle mit einem neuen Kennwort wie folgt geschrieben :

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

Dies ist in meinem Fall natürlich nicht hilfreich, obwohl es eine interessante Methode zum Generieren von zufälligen Passwörtern bietet.


Basierend auf den bisherigen Antworten habe ich einen Connect-Vorschlag erstellt, um das Produkt zu unterstützen:

Max Vernon
quelle

Antworten:

6

Sie können eine Verbindung über den DAC ( Dedicated Administrator Connection ) herstellen und die passwordSpalte abrufen sys.sysowners. Verbinden Sie sich zunächst mit:

ADMIN:Server\Instance

Dann:

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

Diese Ansicht ist nur bei Verwendung des DAC sichtbar, und die Spalte wird in der übergeordneten Ansicht, die sichtbar ist ( sys.database_principals), nicht angezeigt . Bitte seien Sie natürlich vorsichtig mit dem DAC.

Das alles sagte, das hilft dir nicht. CREATE APPLICATION ROLEunterscheidet sich stark davon CREATE LOGIN, dass Sie kein Hash- Passwort angeben können, sondern nur einfachen Text. Denken Sie nicht einmal an das Reverse Engineering des Hash-Werts, da moderne Versionen von SQL Server ausgefeilte Methoden zum Verschlüsseln eines Kennworts verwenden. Wenn Sie dies selbst versuchen, werden Sie feststellen, dass jedes Mal ein anderer Hash erstellt wird, selbst in derselben Anweisung:

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

Ergebnisse (diesmal auf meinem Computer), wobei zu beachten ist, dass Ihre Ergebnisse variieren werden:

0x0200185968C35F22AF70...   0x0200D6C77A1D84A8467F...

Also würde ich entweder empfehlen:

  1. Speichern des Anwendungskennworts in der Quellcodeverwaltung irgendwo oder überall dort, wo Sie derzeit andere Systemkennwörter speichern, und Verwenden dieses Kennworts zum Generieren des Skripts zum Bereitstellen der Anwendungsrollen auf einem anderen Server (oder zur Quellcodeverwaltung des gesamten CREATE APPLICATION ROLESkripts); oder,
  2. Verwenden regulärer Rollen anstelle von Anwendungsrollen.
Aaron Bertrand
quelle
1

Die Syntax enthält nichts, was dies ermöglicht

CREATE APPLICATION ROLE(Transact-SQL) - Online-Bücher

Sie können dies umgehen, indem Sie die Genehmigung in einer Vorlagendatenbank erstellen und das Skript diese wiederherstellen lassen. Eine Implementierung (Dynamics NAV) erstellt eine Code-Genehmigung und speichert das verschlüsselte Anwendungsrollenpasswort in einer Tabelle in der Datenbank, sodass der Client das Rollenpasswort entschlüsselt.

Spörri
quelle