关于c#:使用基本身份验证的HttpWebRequest

HttpWebRequest using Basic authentication

我正在尝试通过一个模仿"基本身份验证请求"的身份验证请求,这种身份验证我们通常在设置IIS时用于此行为。

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

该服务器作为应用程序服务器在UNIX和Java下运行。

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

1
2
3
4
5
6
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();

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

The underlying connection was closed: An unexpected error occurred on
a send.

我想我已经尽了我所有关于C#的知识所能提供的一切可能的任务,但是没有任何事情...


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

只需输入名称" Authorization"和值" Basic BASE64({USERNAME:PASSWORD})"即可

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

编辑

将编码从UTF-8切换为ISO 8859-1,对于HTTP基本身份验证应使用哪种编码?和耶隆的评论。


我终于明白了!

1
2
3
4
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()

1
2
3
4
5
6
7
8
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;
}

好极了!


如果可以使用WebClient类,则使用基本身份验证变得简单:

1
2
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");


尝试这个:

1
2
3
4
5
6
7
8
9
10
11
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;


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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响应。还将解决IIS 7.5 Hosting Problm。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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;
}


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

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


以下构造对我而言无法正常工作:

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

我改用CredentialCache

1
2
3
4
5
6
7
8
CredentialCache credentialCache = new CredentialCache
{
    {
        new Uri($"http://{request.Host}/"),"Basic",
        new NetworkCredential("user","pass")
    }
};
request.Credentials = credentialCache;

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

1
2
3
4
5
6
7
8
9
10
11
12
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);
    }
}

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