使用基本身份验证的 HttpWebRequest

我正在尝试通过一个身份验证请求,该请求模仿了在为此行为设置 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 # 知识能提供给我的所有可能的任务,但是没有..。

413668 次浏览

试试这个:

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;

我终于明白了!

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

耶!

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

只需使名称为“ Authorization”,值为“ BasicBase64({ 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);

剪辑

按照 对于 HTTP 基本身份验证,我应该使用什么编码?和 Jeroen 的注释将编码从 UTF-8切换到 ISO 8859-1。

如果可以使用 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");

规范可以读作“ ISO-8859-1”或“未定义”。你自己选吧。众所周知,许多服务器使用 ISO-8859-1(不管喜欢与否) ,当您发送其他内容时,它们会失败。

有关更多信息和修复这种情况的建议,请参见 http://greenbytes.de/tech/webdav/draft-reschke-basicauth-enc-latest.html

对于那些使用 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;

如果实现了基本身份验证和代理,下面的代码将解决 json 响应问题。

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

下面的结构对我来说并不正确:

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

我希望它将来能帮助某人。

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

其次,我必须发送 BasicAuth 请求和一些数据(表单 urlencode)。在尝试了许多解决方案之后,这里有一个完整的样本,对我来说非常有效。

免责声明: 下面的代码是在这个链接和一些其他堆栈溢出链接上找到的解决方案的混合体,感谢有用的信息。

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

为什么顶级答案和其他答案不适合你的一个原因是因为它缺少一个关键的线。(注意,许多 API 手册忽略了这一必要性)

request.PreAuthenticate = true;

下面是如何在 C # 中执行 Http 基本认证字符串

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