簡體   English   中英

CLR用戶定義的功能安全異常

[英]CLR User-Defined function security exception

我創建了CLR用戶定義函數,以使用Google地理編碼查找位置的緯度和經度信息。 功能如下:

using System;
using System.Net;
using System.Xml.XPath;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

public partial class latlong
{
[Microsoft.SqlServer.Server.SqlFunction]

public static SqlString GetLatLong(string address, string city, string state, string zip)
{
    string latitude = "#NA", longitude = "#NA";
    string url = "http://maps.googleapis.com/maps/api/geocode/xml?address=";
    string[] addresssplit = Regex.Split(address, @"\W+");
    if (address != "NULL")
        for (int i = 0; i < addresssplit.Length; i++)
            url = url + addresssplit[i] + "+";
    if (city != "NULL")
    {
        if (state != "NULL")
        {
            if (zip != "NULL") url = url + city + "+" + state + "+" + zip;
            else url = url + city + "+" + state;
        }
        else
        {
            if (zip!= "NULL") url = url + city + "+" + zip;
            else url = url + city;
        }
    }
    else
    {
        if (state != "NULL")
        {
            if (zip != "NULL") url = url + state + "+" + zip;
            else url = url + state;
        }
        else
        {
            if (zip != "NULL") url = url + zip;
        }
    }
    url = url + "&sensor=false";

    WebResponse response = null;
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "GET";
    response = request.GetResponse();
    if (response != null)
    {
        XPathDocument document = new XPathDocument(response.GetResponseStream());
        XPathNavigator navigator = document.CreateNavigator();
        XPathNodeIterator statusIterator = navigator.Select("/GeocodeResponse/status");
        while (statusIterator.MoveNext())
            if (statusIterator.Current.Value != "OK")
            {
                Thread.Sleep(1000);
                return new SqlString("OQL, OQL");
            }
        XPathNodeIterator resultIterator = navigator.Select("/GeocodeResponse/result");
        while (resultIterator.MoveNext())
        {
            XPathNodeIterator geometryIterator = resultIterator.Current.Select("geometry");
            while (geometryIterator.MoveNext())
            {
                XPathNodeIterator locationIterator = geometryIterator.Current.Select("location");
                while (locationIterator.MoveNext())
                {
                    XPathNodeIterator latIterator = locationIterator.Current.Select("lat");
                    while (latIterator.MoveNext())
                        latitude = latIterator.Current.Value;
                    XPathNodeIterator longIterator = locationIterator.Current.Select("long");
                    while (longIterator.MoveNext())
                        longitude = longIterator.Current.Value;
                }
            }
        }
    }
    Thread.Sleep(1000);
    return new SqlString(latitude + ", " + longitude);
}
}

我已經成功構建並部署了該功能。 因此,我嘗試按以下步驟在SQL Server中執行該函數:

SELECT dba.dbo.GetLatLong('3366 Cherry Avenue','Zion','WI','54963')

當我這樣做時,將引發以下安全性表達式

A .NET Framework error occurred during execution of user-defined routine or aggregate "GetLatLong": 
System.Security.SecurityException: Request for the permission of type 'System.Net.WebPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
System.Security.SecurityException: 
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.CodeAccessPermission.Demand()
at System.Net.HttpWebRequest..ctor(Uri uri, ServicePoint servicePoint)
at System.Net.HttpRequestCreator.Create(Uri Uri)
at System.Net.WebRequest.Create(Uri requestUri, Boolean useUriBase)
at latlong.GetLatLong(String address, String city, String state, String zip).

我可以看到安全權限存在問題。 但是除此之外,我看不到解決異常的方法。

任何幫助表示贊賞。

為了從sql clr代碼發出網絡請求,必須使用EXTERNAL_ACCESS權限配置程序集。 您可以使用CREATE ASSEMBLY語句設置指定的權限

您需要使用EXTERNAL_ACCESS *權限聲明您的過程:

EXTERNAL_ACCESS程序集具有與SAFE程序集相同的權限,並具有訪問外部系統資源(如文件, 網絡 ,環境變量和注冊表)的附加功能。

(我的重點


*或UNSAFE ,但我要說EXTERNAL_ACCESS除非或直到證明您確實需要UNSAFE為止。

在sql中運行:

ALTER DATABASE databasename SET TRUSTWORTHY ON
USE master
GO
grant external access assembly to [domain\computerusername]
grant external access assembly to sa

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM