使用 WebClient 访问时,ASP.NET MVC 应用程序返回未授权 (401) 进行重定向

Posted

技术标签:

【中文标题】使用 WebClient 访问时,ASP.NET MVC 应用程序返回未授权 (401) 进行重定向【英文标题】:ASP.NET MVC Application returns Unauthorized (401) for redirect when accessing with WebClient 【发布时间】:2012-11-22 10:04:15 【问题描述】:

我有一个简单的 ASP.NET MVC 站点,其中包含一个控制器和一些操作。用户需要登录才能访问任何操作(Windows 身份验证、控制器类上的“授权”属性)。

通过浏览器访问网站时一切正常。

在客户端,我还想通过 System.Net.WebClient 访问该站点。我设置了凭据和返回 View 的所有操作都可以正常工作。

但是当我尝试访问一个尝试进行重定向的操作时(使用控制器的 Rediret() 方法),服务器返回 401 Unauthorized。

我已阅读有关 WebClient 和 Windows 身份验证的问题,但我发现的内容似乎不适用于此处,因为除了重定向之外一切正常。

【问题讨论】:

附加信息:我尝试使用 Fiddler 进行调试。在 Fiddler 运行时,一切正常。很奇怪。 【参考方案1】:

所以几周后我有一些时间来解决这个问题,事实证明,它与 ASP.NET 根本没有关系,这是 WebClient 的错。 WebClient 在进行重定向之前会清除其凭据,因此在这种情况下,原始请求是成功的,但是当 WebClient 尝试访问它已重定向到的页面时发生了错误,因为目标也需要身份验证。

不幸的是,您不能仅通过属性切换此行为。所以我的解决方案是这样的。

//Credentials necessary for the request(s)
var cred = new NetworkCredential(username, password);

//Create initial request
var request = (HttpWebRequest)WebRequest.Create(url);
request.AllowAutoRedirect = false;
request.Credentials = cred;

//Get response to first request
var response = (HttpWebResponse)request.GetResponse();

//Follow redirects
while (response.StatusCode == HttpStatusCode.Redirect && maxRedirects > 0)

    //Build new URI for redirect target
    var uri = response.ResponseUri;
    url = String.Format("0://1:23", uri.Scheme, uri.Host, uri.Port, response.GetResponseHeader("Location"));    

    //Create new request
    request = (HttpWebRequest)WebRequest.Create(url);
    request.AllowAutoRedirect = false;
    request.Credentials = cred;

    //Get new response
    response = request.GetResponse() as HttpWebResponse;

    maxRedirects--;


//Get the response's content
var sReader = new StreamReader(response.GetResponseStream());
string responseStr = sReader.ReadToEnd();

我没有使用 WebClient,而是使用 HttpWebRequest 和 HttpWebResponse 并手动执行重定向。在发出请求之前,我设置了完成请求所需的凭据

【讨论】:

【参考方案2】:

我在 HttpWebRequest 代码中找到了描述如何解决此问题的注释:

// Do _not_ automatically reuse the credential object on a redirection unless
// it is specifically a CredentialCache or SystemNetworkCredential object.
//
// The CredentialCache object stores credentials for specific URIs and
// authentication schemes.  Therefore the application has given explicit
// permission to use/send those credentials to a specific site using a
// specific authentication scheme.
//
// A SystemNetworkCredential object represents current default credentials.
// It is deemed safe to reuse them on an automatic redirection since the
// authentication SSP are trusted to only use safe authentication schemes
// for default credentials.

因此,要让我的凭据用于重定向,我所要做的就是创建一个 CredentialCache 对象,而不仅仅是一个 NetworkCredential 对象。

【讨论】:

以上是关于使用 WebClient 访问时,ASP.NET MVC 应用程序返回未授权 (401) 进行重定向的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET使用WebMethod

使用 JQuery 访问 ASP.net Web 服务时出错 - JSONP

理解ASP.NET Core

使用 ASP.NET 网站中的 File.CreateFile 将文件插入 Sql Server 2012 FileTable 时访问被拒绝

C#:使用 IQueryable 注入 DbContext 时,无法访问 ASP.NET Core 中的已处置对象

在 Apache 上运行 ASP.net MVC 时无法访问 elmah.axd