2

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

通过浏览器访问该站点时,一切正常。

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

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

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

4

2 回答 2

0

我在描述如何解决这个问题的 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 对象。

于 2014-07-02T23:26:23.433 回答
0

所以几周后我有一些时间来解决这个问题,事实证明,它与 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}:{2}{3}", 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 并手动遵循重定向。在发出请求之前,我设置了完成请求所需的凭据

于 2013-01-25T20:47:49.063 回答