简体   繁体   English

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

[英]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.

相关问题 重定向(“/错误/未授权”)在 ASP.NET MVC 中不起作用 - Redirect(“/Error/UnAuthorized”) not working in ASP.NET MVC ASP.NET CORE REST API(401 未经授权) - ASP.NET CORE REST API (401 Unauthorized) ASP.NET MVC重定向 - ASP.NET MVC Redirect 在我的asp.net mvc Web应用程序中使用带有WebClient()的Parallel.Foreach有任何缺点或风险吗? - are there any drawbacks or risks of using Parallel.Foreach with WebClient() inside my asp.net mvc web application ASP.NET MVC - 如何在登录页面上显示未经授权的错误? - ASP.NET MVC - How to show unauthorized error on login page? ASP.Net Core 3 API 总是返回 401-JwtBearer - ASP.Net Core 3 API always returns 401- JwtBearer 使用受 JWT 保护的.Net Core WebAPI,来自.Net Core MVC 应用程序始终返回 401 Unauthorized - Consuming .Net Core WebAPI protected with JWT, from .Net Core MVC Application always returning 401 Unauthorized ASP.Net MVC 重定向到不同的视图 - ASP.Net MVC Redirect To A Different View ASP.NET MVC从属性重定向 - ASP.NET MVC redirect from attribute 使用ASP.NET Web API 2和Owin的基于令牌的身份验证会抛出401未授权 - Token Based Authentication using ASP.NET Web API 2 and Owin throws 401 unauthorized
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM