如何处理与HttpWebRequest.AllowAutoRedirect authenticati

2019-08-02 03:53发布

根据MSDN ,当HttpWebRequest.AllowAutoRedirect属性为true,重定向将清除认证头。 给出的解决方法是实施IAuthenticationModule办理身份验证:

该授权头在自动重定向清除,HttpWebRequest的自动尝试重新进行身份验证,以重定向的位置。 在实践中,这意味着应用程序不能把自定义的验证信息到Authorization头,如果有可能遇到的重定向。 相反,应用程序必须实现和注册自定义验证模块。 该System.Net.AuthenticationManager和相关的类来实现自定义的认证模块。 该方法AuthenticationManager.Register注册自定义验证模块。

我创造了这个接口的基本实现:

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))))));
    }
}

和一个简单的驱动程序行使的功能:

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上我的课方法被调用,并验证成功。 当我作出这样一个reutrns 307(临时重定向)响应的请求,没有我的课的方法被调用,并验证失败。 这里发生了什么?

我宁愿不禁用自动重定向和编写自定义的逻辑来处理3xx响应自己。 我怎样才能让我的认证逻辑与自动重定向工作?

Answer 1:

在地方的NetworkCredential的,你应该通过为request.Credentials一个CredentialCache。

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

根据MSDN文档:

CredentialCache类存储凭据多个互联网资源。 需要在需要时访问多个资源可以存储这些资源的凭据在CredentialCache实例,然后提供适当的凭据集互联网资源的应用。 当getCredential方法被调用时,它比较提供与存储在高速缓存中的统一资源标识符(URI)和认证类型,并返回所述第一组匹配的凭据。



Answer 2:

我希望下面将是另一种选择,我从代码项目网址了http://www.codeproject.com/Articles/49243/Handling-Cookies-with-Redirects-and-HttpWebRequest

    String targetUrl = "https://www.SomeUrlThatRequiresAuthentication.com";

    HttpWebRequest request = GetNewRequest(targetUrl);
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();

    while (response.StatusCode ==  HttpStatusCode.MovedPermanently)
    {
        response.Close();
        request = GetNewRequest(response.Headers["Location"]);
        response = (HttpWebResponse)request.GetResponse();
    }


private static HttpWebRequest GetNewRequest(string targetUrl)
{

    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(targetUrl);
    request.AllowAutoRedirect = false;
    request.Headers.Add("Authorization", "Basic xxxxxxxx");
    return request;
}


Answer 3:

尽管OP是很老了,我会提名陨石坑的答案回应。 我通过类似的回旋,包括创建即使是网络资源,我只访问使用基本身份验证的自定义验证模块去了。 我发现,我用了一个CredentialCache后,才,而不是简单的NetworkCredential,做了我的身份验证模块得到重定向后调用。

此外,我发现,因为我需要的认证为基础,仅仅通过供应CredentialCache我并不需要自定义的验证模块在所有 - 标准基本模块的工作就好了。

下面的资源似乎证实了这一点(相对于在OP中提到的.NET文档参考):

https://blogs.msdn.microsoft.com/ncl/2009/05/05/custom-http-authentication-schemes/



Answer 4:

你需要做的可能是一个POST请求。 您发布的变量进行身份验证,因此您需要使用POST动作。

看到这个帖子的详细资料: 登录网站,通过C#

自动重定向不应该在这个岗位要求的方式获得。 我建议你安装小提琴手和手动登录,然后看会发生什么。

*请记住,在发送时POST请求时,如果有一个登录表单,您要发送的POST请求到action='/some-url-or-whatever.php'标签的形式。 POST数据到这一点,你应该能够登录就好了。

让我知道,如果这有助于。



文章来源: How to handle authenticatication with HttpWebRequest.AllowAutoRedirect?