Script d'un rôle d'application avec un mot de passe haché


8

J'ai besoin de créer un script pour un rôle d'application avec un mot de passe haché, afin de pouvoir le copier d'une base de données à une autre.

Prenons l'exemple de code suivant, qui utilise un rôle d'application pour fournir un accès élevé à un utilisateur non approuvé:

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

Une fois que nous avons créé la configuration de test dans tempdb, nous pouvons nous connecter en tant [LimitedLogin]qu'utilisateur et exécuter ce qui suit:

-- login as [LimitedLogin]

USE tempdb;

SELECT *
FROM dbo.Numbers;

L'erreur suivante est renvoyée, comme prévu:

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

Cependant, une fois que nous avons exécuté le sp_setapproleavec le mot de passe approprié, nous pouvons voir les résultats souhaités dans le dbo.Numberstableau:

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;

J'aimerais pouvoir automatiser la création du rôle d'application en le scriptant à partir d'une base de données source à appliquer à une base de données de destination. Je peux facilement effectuer la majorité de cela en:

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

Cependant, j'aimerais vraiment pouvoir avoir le mot de passe haché dans le script, quelque chose comme:

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

Est-ce possible? Vraisemblablement, la version hachée du mot de passe du rôle d'application est stockée quelque part dans la base de données.

À l'aide de la fonctionnalité «Script to ->» de SQL Server Management Studio, le rôle d'application est scripté avec un nouveau mot de passe, comme suit:

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

De toute évidence, cela n'est pas utile dans mon cas, même si cela fournit une méthode intéressante pour générer des mots de passe aléatoires.


Sur la base des réponses jusqu'à présent, j'ai créé une suggestion Connect pour ajouter une prise en charge de ce produit au produit:

Réponses:


6

Vous pouvez vous connecter à l'aide du DAC ( Dedicated Administrator Connection ) et retirer la passwordcolonne de sys.sysowners. Tout d'abord, connectez-vous en utilisant:

ADMIN:Server\Instance

Alors:

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

Cette vue n'est visible que lorsque vous utilisez le DAC et la colonne n'est pas exposée dans la vue parent qui est visible ( sys.database_principals). Veuillez être prudent avec le DAC, bien sûr.

Cela dit, cela ne vous aide pas. CREATE APPLICATION ROLEest très différent de CREATE LOGIN, dans la mesure où vous ne pouvez pas fournir de mot de passe haché , uniquement du texte brut. Et ne pensez même pas à l'ingénierie inverse de la valeur hachée, car les versions modernes de SQL Server utilisent des méthodes élaborées pour crypter un mot de passe. En fait, si vous essayez vous-même, vous verrez qu'un hachage différent est créé à chaque fois, même dans la même déclaration:

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

Résultats (sur ma machine, cette fois), notant que les vôtres varieront:

0x0200185968C35F22AF70...   0x0200D6C77A1D84A8467F...

Donc, je recommanderais soit:

  1. Stocker le mot de passe d'application dans le contrôle de code source quelque part, ou partout où vous stockez actuellement d'autres mots de passe système, et l'utiliser pour générer le script pour déployer les rôles d'application sur un autre serveur (ou contrôle de code source du CREATE APPLICATION ROLEscript entier ); ou,
  2. Utilisation de rôles réguliers au lieu de rôles d'application.

1

Il n'y a rien dans la syntaxe qui rend cela possible

CREATE APPLICATION ROLE(Transact-SQL) - Livres en ligne

Vous pouvez contourner cela en créant l'approle dans une base de données de modèles et demander au script de le restaurer. Une implémentation (Dynamics NAV) crée un approle dans le code et stocke le mot de passe du rôle d'application chiffré dans une table de la base de données, ce qui oblige le client à déchiffrer le mot de passe du rôle.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.