【问题标题】:HttpWebRequest using Basic authentication使用基本身份验证的 HttpWebRequest
【发布时间】:2011-05-19 02:01:05
【问题描述】:

我正在尝试通过一个身份验证请求来模仿我们在为此行为设置 IIS 时经常看到的“基本身份验证请求”。

网址是:https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2
(警告:https!)

此服务器在 UNIX 和 Java 下作为应用服务器运行。

这是我用来连接此服务器的代码:

CookieContainer myContainer = new CookieContainer();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2");
request.Credentials = new NetworkCredential(xxx,xxx);
request.CookieContainer = myContainer;
request.PreAuthenticate = true;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

(我从本网站的另一篇文章中复制了此内容)。但是我从服务器收到了这个答案:

底层连接已关闭:发生意外错误 发送。

我想我尝试了所有可能的任务,我的 C# 知识可以提供给我,但没有...

【问题讨论】:

  • 我认为如果你添加了这个会起作用:request.UseDefaultCredentials = false;

标签: c# authentication credentials webrequest


【解决方案1】:

您也可以自己添加授权标头。

只需将名称设为“Authorization”,并将值设为“Basic BASE64({USERNAME:PASSWORD})”

var username   = "abc";
var password   = "123";
string encoded = System.Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1")
                               .GetBytes(username + ":" + password));
httpWebRequest.Headers.Add("Authorization", "Basic " + encoded);

编辑

根据What encoding should I use for HTTP Basic Authentication? 和 Jeroen 的评论将编码从 UTF-8 切换到 ISO 8859-1。

【讨论】:

  • 那么您如何确定 UTF8 是正确的编码方式?
  • 不错的收获。看起来请求身份验证标头应该以 ISO-8859-1 编码。每stackoverflow.com/questions/7242316/…
  • 啊啊啊! 1:谢谢,伙计。 2. 我真的很想了解为什么其他方法,在 CredentialCache 中设置身份验证方法,根本不起作用。他们应该这样做,不是吗?
  • 所有 msdn 文档都指向是的,其他方法应该可以工作。但是,我一直无法让它们工作。
  • 不适合我(无论是 utf-8 还是 ISO-8859-1)。有什么建议要检查什么?当我执行“ webRequest.Credentials = new NetworkCredential(UserID, Password);”时它可以工作.
【解决方案2】:

我终于明白了!

string url = @"https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2";
WebRequest request = WebRequest.Create(url);
request.Credentials = GetCredential();
request.PreAuthenticate = true;

这是GetCredential()

private CredentialCache GetCredential()
{
    string url = @"https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2";
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
    CredentialCache credentialCache = new CredentialCache();
    credentialCache.Add(new System.Uri(url), "Basic", new NetworkCredential(ConfigurationManager.AppSettings["ead_username"], ConfigurationManager.AppSettings["ead_password"]));
    return credentialCache;
}

耶!

【讨论】:

    【解决方案3】:

    如果可以使用WebClient类,使用基本认证就变得简单了:

    var client = new WebClient {Credentials = new NetworkCredential("user_name", "password")};
    var response = client.DownloadString("https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2");
    

    【讨论】:

      【解决方案4】:

      试试这个:

      System.Net.CredentialCache credentialCache = new System.Net.CredentialCache(); 
      credentialCache.Add(
          new System.Uri("http://www.yoururl.com/"),
          "Basic", 
          new System.Net.NetworkCredential("username", "password")
      );
      
      ...
      ...
      
      httpWebRequest.Credentials = credentialCache; 
      

      【讨论】:

      • 绝对是基本身份验证吗?另外,您可以通过浏览器使用您的用户名/密码访问资源吗?
      • 这似乎是基于 https 的基本身份验证。如果您单击我提供的链接,浏览器会弹出用户名/密码”请求,就像您在 IIS 上执行“基本身份验证”或通过 apache 在文件夹上使用 .htaccss 文件时一样。我尝试使用提琴手,但我不知道。
      • 我刚刚得知该网站在 IBM http 服务器下运行。这可能是一个有用的消息?
      【解决方案5】:

      对于那些使用RestSharp 的人,使用SimpleAuthenticator 时可能会失败(可能是由于未在后台使用ISO-8859-1)。我设法通过显式发送基本身份验证标头来完成它:

      string username = "...";
      string password = "...";
      
      public IRestResponse GetResponse(string url, Method method = Method.GET)
      {
          string encoded = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes($"{username}:{password}"));
          var client = new RestClient(url);
          var request = new RestRequest(method );
          request.AddHeader("Authorization", $"Basic {encoded}");
          IRestResponse response = client.Execute(request);
          return response;
      }
      
      var response = GetResponse(url);
      txtResult.Text = response.Content;
      

      【讨论】:

        【解决方案6】:

        首先,对我来说 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 代替了 Ssl3。

        其次,我必须发送基本身份验证请求以及一些数据(form-urlencoded)。在尝试了许多解决方案之后,这是对我非常有用的完整示例。

        免责声明:下面的代码是在此链接和其他一些 stackoverflow 链接上找到的解决方案的混合体,感谢您提供有用的信息。

                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                String username = "user_name";
                String password = "password";
                String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
        
                //Form Data
                var formData = "var1=val1&var2=val2";
                var encodedFormData = Encoding.ASCII.GetBytes(formData);
        
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create("THE_URL");
                request.ContentType = "application/x-www-form-urlencoded";
                request.Method = "POST";
                request.ContentLength = encodedFormData.Length;
                request.Headers.Add("Authorization", "Basic " + encoded);
                request.PreAuthenticate = true;
        
                using (var stream = request.GetRequestStream())
                {
                    stream.Write(encodedFormData, 0, encodedFormData.Length);
                }
        
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
        

        【讨论】:

        • 非常感谢您的回答。非常适合我!非常感谢!!!
        【解决方案7】:

        如果实施了基本身份验证和代理,以下代码将解决 json 响应。IIS 7.5 Hosting Problm 也将解决。

        public string HttpGetByWebRequ(string uri, string username, string password)
        {
        //For Basic Authentication
            string authInfo = username + ":" + password;
            authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
        
        //For Proxy
            WebProxy proxy = new WebProxy("http://10.127.0.1:8080", true);
        
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
            request.Method = "GET";
            request.Accept = "application/json; charset=utf-8";
            request.Proxy = proxy;
        
            request.Headers["Authorization"] = "Basic " + authInfo;
        
            var response = (HttpWebResponse)request.GetResponse();
        
            string strResponse = "";
            using (var sr = new StreamReader(response.GetResponseStream()))
            {
                strResponse= sr.ReadToEnd();
        
            }
        
            return strResponse;
        }
        

        【讨论】:

        • 不适合我(utf-8、ISO-8859-1 和默认值都不是)。有什么建议要检查吗?请注意 - 当我执行“webRequest.Credentials = new NetworkCredential(UserID, Password);”时它会起作用
        【解决方案8】:

        规范可以读作“ISO-8859-1”或“未定义”。你的选择。众所周知,许多服务器都使用 ISO-8859-1(无论喜欢与否),并且在您发送其他内容时会失败。

        有关更多信息和解决此问题的建议,请参阅http://greenbytes.de/tech/webdav/draft-reschke-basicauth-enc-latest.html

        【讨论】:

          【解决方案9】:

          以下构造对我来说无法正常工作:

          request.Credentials = new NetworkCredential("user", "pass");
          

          我改用CredentialCache

          CredentialCache credentialCache = new CredentialCache
          {
              {
                  new Uri($"http://{request.Host}/"), "Basic",
                  new NetworkCredential("user", "pass")
              }
          };
          request.Credentials = credentialCache;
          

          但是,如果您想添加多个基本身份验证凭据(例如,如果您知道重定向),您可以使用我制作的以下功能:

          private void SetNetworkCredential(Uri uriPrefix, string authType, NetworkCredential credential)
          {
              if (request.Credentials == null)
              {
                  request.Credentials = new CredentialCache();
              }
          
              if (request.Credentials.GetCredential(uriPrefix, authType) == null)
              {
                  (request.Credentials as CredentialCache).Add(uriPrefix, authType, credential);
              }
          }
          

          我希望它对将来的人有所帮助。

          【讨论】:

            【解决方案10】:

            最佳答案和其他答案对您不起作用的一个原因是它缺少关键线。 (请注意,许多 API 手册都忽略了这种必要性)

            request.PreAuthenticate = true;
            

            【讨论】:

              【解决方案11】:

              以下是如何在 C# 中执行 Http Basic Auth 字符串

              string username = "user";
              string password = "pass";            
              var basicAuthBytes = Encoding.GetEncoding("ISO-8859-1").GetBytes($"{username}:{password}");
              var authHeaderValue = $"Basic {System.Convert.ToBase64String(basicAuthBytes)}";
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2014-09-15
                • 2015-08-12
                • 1970-01-01
                • 2017-06-13
                • 2013-05-30
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多