Сценарий роли приложения с помощью хешированного пароля

8

Мне нужно написать сценарий для роли приложения с хешированным паролем, чтобы я мог скопировать его из одной базы данных в другую.

Рассмотрим следующий пример кода, который использует роль приложения для предоставления повышенного доступа ненадежному пользователю:

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

После того, как мы создали тестовую настройку в базе данных tempdb, мы можем войти в систему как [LimitedLogin]пользователь и выполнить следующее:

-- login as [LimitedLogin]

USE tempdb;

SELECT *
FROM dbo.Numbers;

Следующая ошибка возвращается, как и ожидалось:

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

Однако, как только мы выполним sp_setapproleс соответствующим паролем, мы можем увидеть желаемые результаты из dbo.Numbersтаблицы:

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;

Я хотел бы иметь возможность автоматизировать создание роли приложения путем создания сценария из исходной базы данных для применения к целевой базе данных. Я могу легко выполнить большинство из них:

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

Однако мне бы очень хотелось, чтобы в скрипте был хешированный пароль, например:

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

Это возможно? Предположительно хешированная версия пароля роли приложения хранится где-то в базе данных.

Используя функциональность SQL Server Management Studio «script to ->», роль приложения записывается с новым паролем, как:

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

Очевидно, что это не полезно в моем случае, хотя это дает интересный способ генерации случайных паролей.


На основании полученных ответов я создал предложение Connect, чтобы добавить поддержку этого продукта:

Макс Вернон
источник

Ответы:

6

Вы можете подключиться с помощью DAC ( выделенное подключение администратора ) и извлечь passwordстолбец из sys.sysowners. Сначала подключитесь с помощью:

ADMIN:Server\Instance

Затем:

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

Это представление отображается только при использовании DAC, и столбец не отображается в родительском представлении, которое является видимым ( sys.database_principals). Пожалуйста, будьте осторожны с ЦАП, конечно.

Тем не менее, это не поможет вам. CREATE APPLICATION ROLEсильно отличается от того CREATE LOGIN, что вы не можете предоставить хешированный пароль, только обычный текст. И даже не думайте об обратном инжиниринге хэшированного значения, потому что современные версии SQL Server используют сложные методы для шифрования пароля. На самом деле, если вы попробуете это сами, вы увидите, что каждый раз создается новый хэш, даже в одном и том же выражении:

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

Результаты (на моей машине, на этот раз), отметив, что ваши будут отличаться:

0x0200185968C35F22AF70...   0x0200D6C77A1D84A8467F...

Итак, я бы порекомендовал либо:

  1. Хранение пароля приложения в исходном контроле где-либо или там, где вы храните другие системные пароли в настоящее время, и использование его для генерации скрипта для развертывания ролей приложения на другом сервере (или для управления исходным кодом всего CREATE APPLICATION ROLEскрипта); или,
  2. Использование обычных ролей вместо ролей приложений.
Аарон Бертран
источник
1

В синтаксисе нет ничего, что сделало бы это возможным

CREATE APPLICATION ROLE(Transact-SQL) - Электронная литература

Вы можете обойти это, создав апплет в базе данных шаблонов, и скрипт восстановит его. Одна из реализаций (Dynamics NAV) создает согласование в коде и сохраняет зашифрованный пароль роли приложения в таблице базы данных, заставляя клиента расшифровывать пароль роли.

Spörri
источник