Calling an MVC3 action from a SQL CLR stored proce

2019-08-06 17:26发布

问题:

I'm working on a CLR stored procedure that calls a controller action in an ASP.NET MVC3 application that uses Windows Authentication (everything else is disabled). The Web server is IIS 7.5 running on Windows Server 2008 R2 Standard. The database server is SQL Server 2008 R2 Enterprise Edition. Here is the code of the CLR proc:

[SqlProcedure]
public static void UpdateModels()
{
    Uri uri = null;
    HttpWebRequest rq;
    HttpWebResponse rsp;

    Uri.TryCreate("http://testserver/RPM/Configuration/UpdateModels", UriKind.Absolute, out uri);
    rq = (HttpWebRequest)HttpWebRequest.Create(uri);
    rq.Method = WebRequestMethods.Http.Get;
    rsp = (HttpWebResponse)rq.GetResponse();
}

I was able to deploy the assembly to SQL Server without problem, but when I run it, I get the following error:

Msg 6522, Level 16, State 1, Procedure UpdateModels, Line 0
A .NET Framework error occurred during execution of user-defined routine or aggregate "UpdateModels": 
System.Net.WebException: The remote server returned an error: (401) Unauthorized.
System.Net.WebException: 
   at System.Net.HttpWebRequest.GetResponse()
   at StoredProcedures.UpdateModels()
.

This occurs when I call the SP from a SQL Agent job (run under my credentials), when I EXEC it from a SSMS query window (again, my credentials), or any other method I've thought to try. I am an authorized user of the Web application and able to call that controller method just fine from the application itself.

If I change the URL to be just "http://testserver", it runs fine (of course, it doesn't do anything), but if I add "RPM" to the URL, it fails, so it seems the problem is with the application itself, not with the server or its default site. Also, if I enable anonymous auth, it works, so somehow the Windows credentials are not being passed to the site. Checking the log confirms this:

2012-02-23 12:51:33 10.1.1.1 GET /RPM/Configuration/UpdateModels - 80 - 10.2.2.2- 302 0 0 218

The credentials are not being passed. I've tried using impersonation within the CLR SP code, but that has not helped. As I'm sure is obvious, I'm pretty new at this stuff and am probably doing something daft. If someone could set me on the right course, I'd be grateful!

TIA,

Jeff

回答1:

Well, as I feared, I was doing something daft. Turns out impersonation was the answer, but I simply needed to set the impersonation level:

rq.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

before calling the GetResponse method. After doing that, the credentials supplied were passed to the MVC3 controller just as I'd originally expected.

Thought I'd post this just in case anyone else struggles with it the way I did.

Jeff