单个NetworkCredential实例是否仅适用于单个URI

时间:2011-02-05 04:52:45

标签: c# .net authentication redirect

这很可能是关于NetworkCredential类的一个非常天真的问题。请原谅我的经验不足...

我使用用户名,密码和域创建NetworkCredential。然后我使用HttpWebRequest与URI进行交互。 NetworkCredential用于通过设置HttpWebRequest.Credentials对此URI进行身份验证。这一直很好。

然后将一些重定向投入到混合中会导致问题。我现在正在回归401。这是否意味着我的凭证对象仅与特定URI相关联?那会发生什么?我没有在NetworkCredential类中看到发生这种情况的任何地方。

也许设置HttpWebRequest.Credentials的过程将该凭证与仅在HttpWebRequest的构造函数中指定的URI联系起来......

如果是这种情况,如何解决这个问题?

仅供参考,认证方案是Kerberos。我会使用DefaultCredentials,除非用户可能正在使用本地用户帐户(不在Kerberos中)。但是,用户将在程序中输入有效的Kerberos帐户(使用我编写的登录对话框)。

我已经编写了一个方法,它将手动遍历重定向以创建一个NetworkCredential,它指向我要使用的相同主机名(但不是精确的URI)。代码如下:

    /// <summary>
    /// Get a NetworkCredentials instance associated with location.
    /// </summary>
    /// <param name="location">A URI to test user credentials against.</param>
    /// <param name="userName">Username.</param>
    /// <param name="password">Password.</param>
    /// <param name="domain">Domain.</param>
    /// <param name="throwExceptions">Throws exceptions on error if true.</param>
    /// <returns>On success a NetworkCredential instance is returned.  If throwExceptions equals 
    /// true all exceptions will propogate up the stack, otherwise null is returned.</returns>
    public static NetworkCredential GetCredential(Uri location, string userName,
        SecureString password, string domain, bool throwExceptions = true)
    {
        NetworkCredential ret = null;
        try
        {
            Uri uri = location;
            bool redirected = false;
            do
            {
                HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;

                ret = new NetworkCredential(userName, password, domain);
                request.UseDefaultCredentials = false;
                request.Credentials = ret;

                request.AllowAutoRedirect = false;
                HttpWebResponse resp = request.GetResponse() as HttpWebResponse;
                if (resp.StatusCode == HttpStatusCode.Redirect)
                {
                    uri = new Uri(resp.GetResponseHeader("Location"));
                    redirected = true;
                }
                else
                {
                    redirected = false;
                }
            } while (redirected);
        }
        catch
        {
            if (throwExceptions)
            {
                throw;
            }
            ret = null;
        }
        return ret;
    }

1 个答案:

答案 0 :(得分:2)

       // NetworkCredential stores authentication to a single internet resource
       // supplies credentials in password-based authentication schemes such as basic, digest, NTLM, and Kerberos. 
       NetworkCredential networkCredential = new NetworkCredential("username", "password");

        WebRequest webRequest = HttpWebRequest.Create("www.foobar.com");
        webRequest.Credentials = networkCredential;

        // to use the same credential for multiple internet resources...
        CredentialCache credentialCache = new CredentialCache();
        credentialCache.Add(new Uri("www.foobar.com"), "Basic", networkCredential);
        credentialCache.Add(new Uri("www.example.com"), "Digest", networkCredential);

        // now based on the uri and the authetication, GetCredential method would return the 
        // appropriate credentials
        webRequest.Credentials = credentialCache;

herehere

的更多信息