如何使用HttpWebRequest.AllowAutoRedirect处理身份验证? [英] How to handle authenticatication with HttpWebRequest.AllowAutoRedirect?

查看:1103
本文介绍了如何使用HttpWebRequest.AllowAutoRedirect处理身份验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 MSDN ,何时 HttpWebRequest.AllowAutoRedirect 属性为true,重定向将清除身份验证标头。给出的解决方法是实现IAuthenticationModule来处理身份验证:

According to MSDN, when HttpWebRequest.AllowAutoRedirect property is true, redirects will clear authentication headers. The workaround given is to implement IAuthenticationModule to handle authentication:


自动重定向清除Authorization标头,HttpWebRequest自动尝试重新验证到重定向的位置。实际上,这意味着如果可能遇到重定向,应用程序无法将自定义身份验证信息放入Authorization标头中。相反,应用程序必须实现并注册自定义身份验证模块。 System.Net.AuthenticationManager和相关类用于实现自定义身份验证模块。 AuthenticationManager.Register方法注册自定义身份验证模块。

The Authorization header is cleared on auto-redirects and HttpWebRequest automatically tries to re-authenticate to the redirected location. In practice, this means that an application can't put custom authentication information into the Authorization header if it is possible to encounter redirection. Instead, the application must implement and register a custom authentication module. The System.Net.AuthenticationManager and related class are used to implement a custom authentication module. The AuthenticationManager.Register method registers a custom authentication module.

我创建了这个界面的基本实现:

I created a basic implementation of this interface:

public class CustomBasic : IAuthenticationModule
{
    public CustomBasic() { }

    public string AuthenticationType { get { return "Basic"; } }

    public bool CanPreAuthenticate { get { return true; } }

    private bool checkChallenge(string challenge, string domain)
    {
        if (challenge.IndexOf("Basic", StringComparison.InvariantCultureIgnoreCase) == -1) { return false; }
        if (!string.IsNullOrEmpty(domain) && challenge.IndexOf(domain, StringComparison.InvariantCultureIgnoreCase) == -1) { return false; }
        return true;
    }

    public Authorization PreAuthenticate(WebRequest request, ICredentials credentials)
    {
        return authenticate(request, credentials);
    }

    public Authorization Authenticate(String challenge, WebRequest request, ICredentials credentials)
    {
        if (!checkChallenge(challenge, string.Empty)) { return null; }
        return this.authenticate(request, credentials);
    }

    private Authorization authenticate(WebRequest webRequest, ICredentials credentials)
    {
        NetworkCredential requestCredentials = credentials.GetCredential(webRequest.RequestUri, this.AuthenticationType);
        return (new Authorization(string.Format("{0} {1}", this.AuthenticationType, Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", requestCredentials.UserName, requestCredentials.Password))))));
    }
}

以及执行该功能的简单驱动程序:

and a simple driver to exercise the functionality:

public class Program
{
    static void Main(string[] args)
    {
        // replaces the existing handler for Basic authentication
        AuthenticationManager.Register(new CustomBasic());
        // make a request that requires authentication
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(@"https://www.SomeUrlThatRequiresAuthentication.com");
        request.Method = "GET";
        request.KeepAlive = false;
        request.ContentType = "text/plain";
        request.AllowAutoRedirect = true;
        request.Credentials = new NetworkCredential("userName", "password");
        HttpWebResponse result = (HttpWebResponse)request.GetResponse();
    }
}

当我提出不重定向的请求时,调用我的类上的 Authenticate 方法,验证成功。当我提出重新启动307(临时重定向)响应的请求时,不会调用我的类的任何方法,并且身份验证失败。这里发生了什么?

When I make a request that doesn't redirect, the Authenticate method on my class is called, and authentication succeeds. When I make a request that reutrns a 307 (temporary redirect) response, no methods of my class are called, and authentication fails. What's going on here?

我宁愿不禁用自动重定向并编写自定义逻辑来自行处理3xx响应。如何让我的身份验证逻辑与自动重定向一起使用?

I'd rather not disable auto redirect and write custom logic to handle 3xx responses myself. How can I get my authentication logic to work with auto redirect?

推荐答案

您应该传递一个CredentialCache来代替NetworkCredential request.Credentials。

In place of the NetworkCredential, you should pass a CredentialCache for the request.Credentials.

CredentialCache cache = new CredentialCache();
cache.Add(new Uri(@"https://www.SomeUrlThatRequiresAuthentication.com", "Basic", new NetworkCredential("username", "password"));
request.Credentials = cache;

根据MSDN文档:


CredentialCache类存储多个Internet
资源的凭据。需要访问多个资源的应用程序可以
将这些资源的凭据存储在CredentialCache
实例中,然后在需要时为
Internet资源提供适当的凭据集。当GetCredential方法被
调用时,它会比较统一资源标识符(URI)和
身份验证类型,以及存储在cache和
返回匹配的第一组凭据。

The CredentialCache class stores credentials for multiple Internet resources. Applications that need to access multiple resources can store the credentials for those resources in a CredentialCache instance that then provides the proper set of credentials to the Internet resource when required. When the GetCredential method is called, it compares the Uniform Resource Identifier (URI) and authentication type provided with those stored in the cache and returns the first set of credentials that match.

这篇关于如何使用HttpWebRequest.AllowAutoRedirect处理身份验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆