When we are trying to deploy an assembly with PERMISSION_SET=UNSAFE or EXTERNAL_ACCESS, we are getting following error message by 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.**
We are not setting database trustworthy=ON, instead we are creating asymmetric key using ALGORITHM = RSA_2048. Following is the sample code:
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
But this error is not getting resolved. I even provided sysadmin access to SampleClrLogin login for my database and master database, but it did not work. Can you guys please provide some insight to solve this issue.
Best Answer
The problem is that you are creating a random new Asymmetric Key in SQL Server, which does nothing to associate the Login to the Assembly, which is what the Asymmetric Key (or Certificate) is used for.
You need to first sign the Assembly prior to loading it into SQL Server. Whether it is signed with a strong name key (which equates to an Asymmetric Key within SQL Server) or a Certificate, you then create that same Asymmetric Key or Certificate (only the public key is required) in
master
and then create the signature-based Login from that.For examples on how to accomplish this (and in a way that can be automated via Visual Studio / SSDT), please see the series I am writing on working with SQLCLR (on SQL Server Central): Stairway to SQLCLR (Levels 7 and 8 in particular).
If you are working with SQL Server 2017 or newer, then there is an additional complication to account for which is not part of the method described in the SQL Server central articles. For that, please see the two options for the revised approach in my posts:
P.S. Thank you for spending the extra few minutes to not enable TRUSTWORTHY :-)
CLARIFICATION
Since you are trying to load an unsupported .NET Framework library, you won't be compiling that yourself so the steps I outlined above will not work here (though they are still relevant for someone simply misunderstanding and trying to create the Asymmetric Key initially within SQL Server as shown in the question).
But, given that:
System.ServiceModel.Internals
and notSystem.ServiceModel
, andthen you can accomplish this (while keeping
TRUSTWORTHY OFF
!) by doing the following:And then:
Just keep in mind that this technique does not work with
System.ServiceModel.dll
. That library went from being pure MSIL pre-.NET 4.0 to mixed in .NET 4.0, and only pure MSIL libraries can be loaded into SQL Server. UsingServiceModel
worked in SQL Server 2005, 2008, and 2008 R2 because those versions use CLR 2.0 which is tied to .NET Framework versions 2.0, 3.0, and 3.5 in whichServiceModel
was pure-MSIL.But in general, David Browne is correct in that you should probably be using
HttpWebRequest
instead (depending on what you need System.ServiceModel.Internals for).