ハッシュされたパスワードでアプリケーションロールをスクリプト化する


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)。もちろん、DACには気をつけてください。

つまり、これはあなたを助けません。 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) -Books Online

テンプレートデータベースにapproleを作成してこれを回避し、スクリプトにそれを復元させることができます。1つの実装(Dynamics NAV)は、コードでapproleを作成し、暗号化されたアプリケーションロールパスワードをデータベースのテーブルに格納して、クライアントにロールパスワードを復号化させます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.