web-dev-qa-db-ja.com

非対称キーを使用したUNSAFEまたはEXTERNAL_ACCESSの権限を持つアセンブリの配置

PERMISSION_SET = UNSAFEまたはEXTERNAL_ACCESSを使用してアセンブリを配置しようとすると、SQL Serverから次のエラーメッセージが表示されます。

 CREATE Assembly for Assembly 'System.ServiceModel.Internals' failed because 
 Assembly 'System.ServiceModel.Internals' is not authorized for 
 PERMISSION_SET = UNSAFE.  The Assembly is authorized when either of the 
 following is true: the database owner (DBO) has UNSAFE Assembly permission 
 and the database has the TRUSTWORTHY database property on; or the Assembly 
 is signed with a certificate or **an asymmetric key that has a 
 corresponding login with UNSAFE Assembly permission.**

データベースをtrustworthy = ONに設定するのではなく、ALGORITHM = RSA_2048を使用して非対称キーを作成します。次にサンプルコードを示します。

USE master; 
GO  

IF NOT EXISTS (SELECT 1 FROM sys.asymmetric_keys WHERE [name]='SampleClrKey')
BEGIN
      CREATE ASYMMETRIC KEY [SampleClrKey] WITH ALGORITHM = RSA_2048
      CREATE LOGIN [SampleClrLogin] FROM ASYMMETRIC KEY [SampleClrKey];  
      GRANT UNSAFE Assembly TO [SampleClrLogin];
 END
GO

しかし、このエラーは解決されていません。データベースとマスターデータベースのSampleClrLoginログインへのsysadminアクセスを提供しましたが、機能しませんでした。この問題を解決するための洞察を提供してください。

2

問題は、SQL Serverでランダムな新しい非対称キーを作成していることです。これは、非対称キー(または証明書)が使用されるアセンブリへのログインを関連付けることは何もしません。

SQL Serverにアセンブリをロードする前に、firstアセンブリに署名する必要があります。厳密な名前のキー(SQL Server内の非対称キーに相当)で署名されているか、証明書で署名されているかに関係なく、masterに同じ非対称キーまたは証明書(公開キーのみが必要)を作成し、次にそれから署名ベースのログインを作成します。

これを実現する方法の例(およびVisual Studio/SSDTを介して自動化できる方法)については、SQLCLR(SQL Server Central上)の操作について書いているシリーズを参照してください。 SQLCLRへの階段 =(特にレベル7および8)。

SQL Server 2017以降を使用している場合は、SQL Serverの中心的な記事で説明されている方法の一部ではないため、さらに複雑な問題があります。それについては、私の投稿で修正されたアプローチの2つのオプションを参照してください。

追伸 notenable TRUSTWORTHY :-)に余分な数分を費やしていただきありがとうございます


[〜#〜]説明[〜#〜]

サポートされていない.NET Frameworkライブラリをロードしようとしているので、自分でコンパイルすることはないため、上記で概説した手順はここでは機能しません(ただし、これらの手順は、単に誤解し、最初に非対称キーを作成しようとしている人に関連しています)質問に示されているSQL Server)。

しかし、それを考えると:

  1. System.ServiceModel.InternalsではなくSystem.ServiceModelを読み込もうとしています。
  2. 特定のライブラリが「不正な形式であるか、純粋な.NETアセンブリではない」というエラーがない

その後、次のようにすることで(TRUSTWORTHY OFF!を維持しながら)これを実現できます。

USE [master];
CREATE CERTIFICATE [UnsupportedFrameworkLibraryPermissions]
  FROM EXECUTABLE FILE =
  'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.ServiceModel.Internals.dll';

CREATE LOGIN [UnsupportedFrameworkLibraryPermissions]
  FROM CERTIFICATE [UnsupportedFrameworkLibraryPermissions];

GRANT UNSAFE Assembly TO [UnsupportedFrameworkLibraryPermissions];

その後:

USE [{your_DB_name_here}];

CREATE Assembly [System.ServiceModel.Internals]
  FROM 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.ServiceModel.Internals.dll'
  WITH PERMISSION_SET = UNSAFE;

このテクニックはSystem.ServiceModel.dllでは機能しないことに注意してください。そのライブラリは、純粋なMSIL以前の.NET 4.0から.NET 4.0での混合に移行し、純粋なMSILライブラリのみをSQL Serverにロードできます。 ServiceModelの使用はSQL Server 2005、2008、および2008 R2で機能しました。これらのバージョンは、ServiceModelが純粋なMSILである.NET Frameworkバージョン2.0、3.0、および3.5に関連付けられたCLR 2.0を使用するためです。 。

しかし、一般的には、代わりにHttpWebRequestを使用する必要があるという点で、David Browneは正しいです(必要なものに応じてSystem.ServiceModel.Internals ために)。

2
Solomon Rutzky

System.ServiceModel.Internals

すぐに停止できます。 WCFはSQL CLRでは使用できません。 SQL CLRは純粋なMSILアセンブリのみをサポートし、.NET 4.xのWCFはいくつかの混合モードアセンブリを参照します。

参照 サポートされているリストにない.NETフレームワークアセンブリを登録できません

および https://stackoverflow.com/questions/40349838/sql-server-2016-create-Assembly-for-Assembly-system-servicemodel-failed

SQL CLRからWebサービスを呼び出す場合は、 WebClient API 、または下位レベルの HttpWebRequest を使用できます。どちらもSystem.dllに実装されています。