Lorsque j'essaie de créer un assemblage dans SQL 2008 à partir d'un assemblage .Net (.Net 3.5), j'obtiens l'erreur ci-dessous, l'erreur indique que je dois définir l'une des propriétés ci-dessous comme vraie, comment puis-je faire cela?
Le propriétaire de la base de données (DBO) dispose de la permission EXTERNAL ACCESS Assembly sur TRUE
La base de données a la propriété de base de données TRUSTWORTHY sur
L'assembly est signé avec un certificat ou une clé asymétrique qui a une connexion correspondante avec l'autorisation d'assembly ACCÈS EXTERNE.
L'erreur complète est ci-dessous,
CREATE L'assembly pour l'assembly 'SQLLogger' a échoué car l'assembly 'SQLLogger' n'est pas autorisé pour PERMISSION_SET = EXTERNAL_ACCESS. L'assembly est autorisé lorsque l'une des conditions suivantes est remplie: le propriétaire de la base de données (DBO) a l'autorisation d'accès EXTERNAL ACCESS et la base de données possède la propriété de base de données TRUSTWORTHY; ou l'assembly est signé avec un certificat ou une clé asymétrique qui a une connexion correspondante avec l'autorisation d'assembly ACCÈS EXTERNE.
Merci d'avance!
Vous devez définir ces paramètres dans le fichier de projet! Lorsque vous faites un clic droit sur votre projet, cliquez sur les paramètres de la base de données dans la configuration du projet et sélectionnez l'onglet divers. Vous devriez voir quelque chose de similaire à ce que j'ai ici:
C'est la même question que: Erreur lors de l'exécution de CLR Stored Proc
Cela a fonctionné pour moi:
EXEC sp_changedbowner 'sa'
ALTER DATABASE [dbase] SET trustworthy ON
et j'ai aussi fait ça:
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'clr enabled', 1;
GO
RECONFIGURE;
GO
sp_configure 'show advanced options', 0;
GO
RECONFIGURE;
GO
Veuillez ne pas définir TRUSTWORTHY ON
sauf si absolument nécessaire! Et cela ne devrait être "nécessaire" que lors du chargement d'un assembly que vous n'avez pas construit et que vous ne pouvez pas signer de nouveau. Et cela se produit principalement lors du chargement de bibliothèques .NET Framework qui ne sont pas "prises en charge" et donc pas déjà dans l'hôte CLR de SQL Server. En dehors de ces circonstances, vous ne devez pas définir la base de données sur TRUSTWORTHY ON
car il ouvre un trou de sécurité.
Au lieu de cela, il est préférable de procéder comme suit:
USE [master];
CREATE ASYMMETRIC KEY [SomeKey]
AUTHORIZATION [dbo]
FROM EXECUTABLE FILE = 'C:\path\to\Some.dll';
CREATE LOGIN [SomeLogin]
FROM ASYMMETRIC KEY [SomeKey];
GRANT EXTERNAL ACCESS Assembly TO [SomeLogin]; -- or "UNSAFE" instead of "EXTERNAL ACCESS"
Ce qui précède ne doit être effectué qu'une fois par instance, par clé. Donc, si vous utilisez le même fichier snk
/pfx
pour tous vos assemblys, les étapes indiquées ci-dessus ne doivent être effectuées qu'une seule fois par instance SQL Server; le nombre d'assemblages et de bases de données contenant ces assemblages n'a pas d'importance.
Cette approche vous permet de conserver une meilleure sécurité sur la base de données (en conservant TRUSTWORTHY
défini sur OFF
) et permet un contrôle plus précis des assemblys qui peuvent même être définis sur EXTERNAL_ACCESS
et/ou UNSAFE
(puisque vous pouvez vous séparer en utilisant différentes clés pour la signature et des connexions basées sur ces différentes clés).
Cependant, si vous devez utiliser le TRUSTWORTHY ON
, le propriétaire de la base de données n'a pas besoin d'être sa
. La condition est simplement que la connexion enregistrée en tant que propriétaire de la base de données ait été accordée EXTERNAL ACCESS Assembly
ou UNSAFE Assembly
(les deux mêmes autorisations indiquées ci-dessus pour la connexion basée sur une clé asymétrique).
Pour une présentation plus détaillée des options de sécurité, consultez l'article suivant que j'ai écrit sur SQL Server Central: Escalier vers SQLCLR niveau 4: sécurité (assemblages externes et non sûrs) (inscription gratuite est requis).
Pour une procédure détaillée sur la façon d'automatiser cela via Visual Studio/SSDT, veuillez consulter les 3 articles suivants (une série en 3 parties), également sur SQL Server Central:
De plus, depuis la rédaction de ces 3 articles, j'ai trouvé une méthode plus simple en utilisant des modèles T4 mais je n'ai pas encore eu le temps de l'écrire. Lorsque je le ferai, je mettrai à jour cette réponse avec un lien vers cet article.
SQL Server 2017 a introduit une nouvelle complication sous la forme d'une option de configuration au niveau du serveur appelée "sécurité stricte CLR". Il est activé par défaut et nécessite que TOUS les assemblys, même ceux marqués comme SAFE
, soient signés avec un certificat ou une clé asymétrique, aient la connexion associée, et que la connexion a le UNSAFE Assembly
autorisation accordée (insuffisante pour accorder EXTERNAL ACCESS Assembly
). Veuillez voir ma réponse au S.O. question pour plus de détails sur cette nouvelle "fonctionnalité":
Le code suivant a fonctionné pour moi pour la sécurité intégrée:
ALTER DATABASE dtabasename SET TRUSTWORTHY ON;
GO
ALTER AUTHORIZATION ON DATABASE::dtabasename TO [DOMAIN\UserName]
GO
Voici comment j'ai réussi à le faire fonctionner:
ALTER DATABASE databasename SET trustworthy ON
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'clr enabled', 1;
GO
RECONFIGURE;
GO
sp_configure 'show advanced options', 0;
GO
RECONFIGURE;
GO
/
DROP Assembly assemblyname
GO
CREATE Assembly assemblyname
FROM 0x4D5A9000.....
WITH PERMISSION_SET = EXTERNAL_ACCESS
Cela fonctionne pour:
Dans les paramètres de votre projet, sélectionnez "Accès externe":
Lors de la publication, le message d'erreur indique qu'il ne peut accepter "EXTERNAL_ACCESS" que si l'assembly est défini sur "Trustworthy".
Ainsi, dans les paramètres du projet, définissez l'assembly sur "Trustworthy":
Cela signifiait que je pouvais exécuter un exemple de fonction définie par l'utilisateur qui répertorie les fichiers sur le disque dur local .
Si la sécurité est encore trop restrictive, ajoutez l'attribut DataAccess = DataAccessKind.Read
à votre UDF, par exemple:
[Microsoft.SqlServer.Server.SqlFunction(FillRowMethodName = "FindFiles", DataAccess = DataAccessKind.Read, TableDefinition = "FileName nvarchar(500), FileSize bigint, CreationTime datetime")]
Sur SQL Server 2016
+ Visual Studio 2015
, vous devrez peut-être également effectuer les opérations suivantes:
use master;grant unsafe Assembly to [Domain\Username];
Administrator
pour leur donner les autorisations suffisantes pour publier les assemblys UNSAFE
.Si rien ne fonctionne, essayez de vous connecter en utilisant le nom d'utilisateur sa
et votre mot de passe administrateur. Cela fonctionnera toujours, que Visual Studio soit exécuté en mode Administrator
ou non.
cette seule ligne résout le problème pour moi
use master;
grant external access Assembly to [domain\username]