2013-04-08 101 views
3

時候我已經用C#編寫一個簡單的用戶定義函數獲取IP地址,並返回主機名反對它的代碼如下:拋出:SecurityException錯誤調用CLR函數

public partial class UserDefinedFunctions 
{ 
    [Microsoft.SqlServer.Server.SqlFunction] 
    public static SqlString getname(String ipAddress) 
    { 
     System.Data.SqlClient.SqlClientPermission pSql = new SqlClientPermission(System.Security.Permissions.PermissionState.Unrestricted); 
     pSql.Assert(); 

     System.Security.PermissionSet psql1 = new PermissionSet(System.Security.Permissions.PermissionState.Unrestricted); 
     psql1.Assert(); 

     System.Net.DnsPermission psql = new DnsPermission(System.Security.Permissions.PermissionState.Unrestricted); 
     psql.Assert(); 

     System.Security.Permissions.SecurityPermission psql2 = new SecurityPermission(System.Security.Permissions.PermissionState.Unrestricted); 
     psql2.Assert(); 

     IPHostEntry host = Dns.GetHostEntry(ipAddress); 
     return new SqlString(host.HostName.ToString()); 
    } 
} 

現在我已經部署了,但是當我嘗試調用這個函數在SQL爲:選擇dbo.getname('10 .10.10.10' )

它返回此錯誤:

Msg 6522, Level 16, State 2, Line 7 
A .NET Framework error occurred during execution of user-defined routine or aggregate "getname": 
System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed. 
System.Security.SecurityException: 
    at System.Security.CodeAccessSecurityEngine.CheckNReturnSO(PermissionToken permToken, CodeAccessPermission demand, StackCrawlMark& stackMark, Int32 unrestrictedOverride, Int32 create) 
    at System.Security.CodeAccessSecurityEngine.Assert(CodeAccessPermission cap, StackCrawlMark& stackMark) 
    at System.Security.CodeAccessPermission.Assert() 
    at UserDefinedFunctions.getname(String ipAddress) 

我已經爬到了互聯網,但找不着什麼。請建議。

+0

你怎麼註冊程序集?是否標記爲外部訪問? – StrayCatDBA 2013-04-24 03:46:59

+0

我從一個非常相似的CLR函數中得到完全相同的錯誤。我使用WindowsIdentity.Getcurrent()來返回用戶信息。我的程序集在SQL WITH PERMISSION_SET = External_Access中註冊。有人解決這個問題嗎? – 2014-10-24 14:58:27

回答

2

您必須創建具有外部訪問權限集的程序集。程序集還必須簽名或將數據庫設置爲可信,並且數據庫所有者授予外部訪問程序集許可權。 上面的權限和斷言代碼不是必需的。

E.g.

using Microsoft.SqlServer.Server; 
using System; 
using System.Data.SqlTypes; 
using System.Net; 

public partial class UserDefinedFunctions 
{ 
    [Microsoft.SqlServer.Server.SqlFunction(DataAccess=DataAccessKind.None)] 
    public static SqlString getname(String ipAddress) 
    { 
     IPHostEntry host = Dns.GetHostEntry(ipAddress); 
     return new SqlString(host.HostName); 
    } 
} 

代碼保存到C:\決心\ resolve.cs並編譯...

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /t:library /out:C:\resolve\resolve.dll C:\resolve\resolve.cs 

複製.dll文件到服務器,如果不是本地實例。然後創建對象...

USE [master] 
GO 
CREATE DATABASE [clr]; 
GO 
ALTER AUTHORIZATION ON DATABASE::[clr] TO [sa]; 
GO 
ALTER DATABASE [clr] SET TRUSTWORTHY ON; 
GO 
USE [clr]; 
GO 
CREATE ASSEMBLY [assResolve] FROM 'C:\resolve\resolve.dll' 
WITH PERMISSION_SET=EXTERNAL_ACCESS; 
GO 
CREATE FUNCTION [fnGetHostName](@ipAddress nvarchar(255)) RETURNS nvarchar(255) 
AS EXTERNAL NAME [assResolve].[UserDefinedFunctions].[getname]; 
GO 
SELECT [dbo].[fnGetHostName](N'8.8.8.8') as [host]; 
GO 
USE [master] 
+0

我不得不改變創建裝配改變裝配和刪除,但除此之外,非常感謝。 – wavydavy 2017-09-25 09:09:27

相關問題