CLR用户定义的函数安全异常。

时间:2022-11-11 16:31:42

I have created a CLR User-defined function to look up the latitude and longitude information of a location using Google geocode. The function is as follows:

我创建了一个CLR用户定义函数,使用谷歌地理代码查找位置的纬度和经度信息。其功能如下:

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);
}
}

I have built and deployed the function successfully. So I tried executing the function in the SQL server as follows:

我已经成功地构建并部署了这个函数。所以我尝试在SQL server中执行如下的函数:

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

When I do so the following security expression is raised

当我这样做时,会引发以下安全表达式

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).

I can see that there is a problem with the security permissions. But beyond that I do not see the way to fix the exception.

我可以看到安全权限有问题。但除此之外,我看不到解决这个异常的方法。

Any help is appreciated.

任何帮助都是感激。

3 个解决方案

#1


2  

In order to make network request from sql clr code the assembly must be configured with EXTERNAL_ACCESS permission. You can set the specified permission by using CREATE ASSEMBLY statement

为了从sql clr代码发出网络请求,必须使用EXTERNAL_ACCESS权限配置程序集。可以使用CREATE ASSEMBLY语句设置指定的权限

#2


0  

You need to declare your procedure with EXTERNAL_ACCESS* permission:

您需要使用EXTERNAL_ACCESS*权限声明过程:

EXTERNAL_ACCESS assemblies have the same permissions as SAFE assemblies, with the additional ability to access external system resources such as files, networks, environmental variables, and the registry.

EXTERNAL_ACCESS程序集具有与安全程序集相同的权限,具有访问外部系统资源(如文件、网络、环境变量和注册表)的附加能力。

(My emphasis)

(我的重点)


*Or UNSAFE, but I'd say EXTERNAL_ACCESS unless or until it's demonstrated that you actually needed UNSAFE.

*或不安全,但我要说的是EXTERNAL_ACCESS,除非或直到证明您确实需要不安全。

#3


0  

Run this in sql:

在sql运行这个:

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

#1


2  

In order to make network request from sql clr code the assembly must be configured with EXTERNAL_ACCESS permission. You can set the specified permission by using CREATE ASSEMBLY statement

为了从sql clr代码发出网络请求,必须使用EXTERNAL_ACCESS权限配置程序集。可以使用CREATE ASSEMBLY语句设置指定的权限

#2


0  

You need to declare your procedure with EXTERNAL_ACCESS* permission:

您需要使用EXTERNAL_ACCESS*权限声明过程:

EXTERNAL_ACCESS assemblies have the same permissions as SAFE assemblies, with the additional ability to access external system resources such as files, networks, environmental variables, and the registry.

EXTERNAL_ACCESS程序集具有与安全程序集相同的权限,具有访问外部系统资源(如文件、网络、环境变量和注册表)的附加能力。

(My emphasis)

(我的重点)


*Or UNSAFE, but I'd say EXTERNAL_ACCESS unless or until it's demonstrated that you actually needed UNSAFE.

*或不安全,但我要说的是EXTERNAL_ACCESS,除非或直到证明您确实需要不安全。

#3


0  

Run this in sql:

在sql运行这个:

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