[英]ASP.NET MVC Application returns Unauthorized (401) for redirect when accessing with WebClient
I have a simple ASP.NET MVC site with a single controller and some actions in it. 我有一个具有单个控制器和其中一些操作的简单ASP.NET MVC网站。 A user needs to log in to access any action (Windows Authentication, 'Authorize' attribue on the controller class).
用户需要登录才能访问任何操作(Windows身份验证,控制器类上的“授权”属性)。
When accessing the site via a browser everything works fine. 通过浏览器访问该站点时,一切正常。
On the client, I would also like to access the site via System.Net.WebClient. 在客户端上,我还想通过System.Net.WebClient访问该站点。 I set the credentials and all actions that return a View work just fine.
我设置了凭据,并且所有返回View工作的操作都很好。
But when I try to access an action that tries to make a redirect (using Controller's Rediret() method) the server returns a 401 Unauthorized. 但是,当我尝试访问尝试进行重定向的操作(使用Controller的Rediret()方法)时,服务器将返回401未经授权。
I've read about problems with WebClient and Windows authentication but the stuff I found does not seem to apply here, because everything works except for the redirects. 我已经阅读了有关WebClient和Windows身份验证的问题,但是我发现的内容似乎不适用于此处,因为除重定向外,其他所有功能都可以使用。
So after some weeks I had some time to come back to this problem and as it turns out, it has nothing to do with ASP.NET at all and it's WebClient's fault. 因此,几周后,我花了一些时间回到这个问题上,事实证明,它与ASP.NET完全无关,这是WebClient的错。 WebClient clears its credentials before following a redirect, so in this case the original request was successful but the error the occurred when WebClient tried to access the page it had been redirected to, because authentication is necessary for the target, too.
WebClient在进行重定向之前会清除其凭据,因此在这种情况下,原始请求成功,但是由于WebClient尝试访问已重定向到的页面时发生错误,因为目标也必须进行身份验证。
Unfortunately, you cannot just toggle this behavior via a Property. 不幸的是,您不能仅通过属性来切换此行为。 So my solution looks like this.
所以我的解决方案看起来像这样。
//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();
Instead of using WebClient, I'm using HttpWebRequest and HttpWebResponse and follow the Redirect manually. 我没有使用WebClient,而是使用HttpWebRequest和HttpWebResponse并手动遵循重定向。 Before making the request, I set the credentials necessary to complete the request
在提出请求之前,我设置了完成请求所需的凭据
I found a comment in the HttpWebRequest code that describes how to solve this issue: 我在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.
So all I had to do to get my credentials to work on redirects is create a CredentialCache object instead of just a NetworkCredential object. 因此,为了使我的凭据能够在重定向上工作,我要做的就是创建一个CredentialCache对象,而不仅仅是一个NetworkCredential对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.