HttpWebRequest sử dụng xác thực cơ bản


137

Tôi đang cố gắng thực hiện một yêu cầu xác thực bắt chước "yêu cầu xác thực cơ bản" mà chúng ta thường thấy khi thiết lập IIS cho hành vi này.

URL là: https://telIALoprova.agenziadogane.it/TelIALoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2
(cảnh báo: https!)

Máy chủ này đang chạy dưới UNIX và Java là máy chủ ứng dụng.

Đây là mã tôi sử dụng để kết nối với máy chủ này:

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

(Tôi đã sao chép nó từ một bài đăng khác trên trang web này). Nhưng tôi nhận được câu trả lời này từ máy chủ:

Kết nối cơ bản đã bị đóng: Xảy ra lỗi không mong muốn khi gửi.

Tôi nghĩ rằng tôi đã thử mọi nhiệm vụ có thể mà kiến ​​thức của tôi về C # phải cung cấp cho tôi, nhưng không có gì ...


Tôi nghĩ cái này sẽ hoạt động nếu bạn đã thêm: request.UseDefaultCredentials = false;
bpeike

Câu trả lời:


273

Bạn cũng có thể chỉ cần thêm tiêu đề ủy quyền cho mình.

Chỉ cần đặt tên "Ủy quyền" và giá trị "Basic BASE64 ({USERNAME: PASSWORD})"

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

Biên tập

Chuyển đổi mã hóa từ UTF-8 sang ISO 8859-1 cho mỗi Tôi nên sử dụng mã hóa nào cho Xác thực cơ bản HTTP? và bình luận của Jeroen.


3
Vậy làm thế nào để bạn biết chắc chắn rằng UTF8 là mã hóa phù hợp để sử dụng?
Jeroen Wiert Pluimers

2
Bắt đẹp. Có vẻ như tiêu đề Xác thực yêu cầu phải được mã hóa theo ISO-8859-1. Mỗi stackoverflow.com/questions/7242316/ Lời
Zambonilli

1
Aaaargh! 1: Cảm ơn, bạn đời. 2. Tôi thực sự muốn hiểu lý do tại sao các phương thức khác, thiết lập phương thức xác thực trong CredentialCache, sẽ không hoạt động. Họ được cho là, phải không?
mshthn

1
Tất cả các tài liệu msDN chỉ đến có, các phương pháp khác sẽ hoạt động. Tuy nhiên, tôi chưa bao giờ có thể khiến họ làm việc.
Zambonilli

Không làm việc cho tôi (không utf-8 hay ISO-8859-1). Bất cứ đề nghị những gì để kiểm tra? Nó hoạt động khi tôi thực hiện "webRequest.Credentials = new NetworkCredential (UserID, Password);" .
RollerCosta

56

Cuối cùng tôi đã nhận được nó!

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;

và đây là 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;
}

YAY!


29

Nếu bạn có thể sử dụng WebClientlớp, việc sử dụng xác thực cơ bản trở nên đơn giản:

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

8

Thử cái này:

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; 

Là nó chắc chắn cơ bản auth? Ngoài ra, bạn có thể truy cập tài nguyên bằng tên người dùng / mật khẩu của mình thông qua trình duyệt không?
MrEyes

Nó có vẻ là một auth cơ bản trên https. Nếu bạn nhấp vào liên kết tôi cung cấp, trình duyệt sẽ bật yêu cầu tên người dùng / mật khẩu "giống như khi bạn thực hiện" auth cơ bản "trên IIS hoặc sử dụng tệp .htaccss trên một thư mục thông qua apache. Tôi đã thử sử dụng fiddler nhưng tôi không có manh mối nào.
Kenny Rullo

Tôi mới biết rằng trang web đang chạy trên máy chủ IBM http. Đây có thể là một tin tức hữu ích?
Kenny Rullo

5

Đối với những người sử dụng RestSharp , nó có thể thất bại khi sử dụng SimpleAuthenticator (có thể do không sử dụng ISO-8859-1 phía sau hậu trường). Tôi đã quản lý để hoàn thành nó bằng cách gửi rõ ràng các tiêu đề Xác thực Cơ bản:

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;

3

Mã sau sẽ giải quyết phản hồi json nếu có Xác thực cơ bản và Proxy được triển khai. Ngoài ra, IIS 7.5 Hosting Problm sẽ giải quyết.

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

Không hoạt động đối với tôi (không utf-8 hay ISO-8859-1 cũng không mặc định). Bất kỳ đề xuất nào cần kiểm tra? Xin lưu ý - Nó hoạt động khi tôi thực hiện "webRequest.Credentials = new NetworkCredential (UserID, Password);"
RollerCosta

2

Thông số kỹ thuật có thể được đọc là "ISO-8859-1" hoặc "không xác định". Lựa chọn của bạn. Được biết, nhiều máy chủ sử dụng ISO-8859-1 (dù muốn hay không) và sẽ thất bại khi bạn gửi thứ khác.

Để biết thêm thông tin và đề xuất khắc phục tình trạng này, hãy xem http://greenbytes.de/tech/webdav/draft-reschke-basicauth-enc-latest.html


1

Việc xây dựng sau đây không hoạt động chính xác với tôi:

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

Tôi đã sử dụng CredentialCachethay thế:

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

Tuy nhiên, nếu bạn muốn thêm nhiều thông tin xác thực cơ bản (ví dụ: nếu có chuyển hướng mà bạn biết), bạn có thể sử dụng chức năng sau mà tôi đã thực hiện:

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

Tôi hy vọng nó sẽ giúp được ai đó trong tương lai.


0

Điều đầu tiên, đối với tôi ServicePointManager.SecurityProtocol = SecurityProtocolType. Tls12 hoạt động thay vì Ssl3.

Thứ hai, tôi đã phải gửi yêu cầu Xác thực cơ bản cùng với một số dữ liệu (biểu mẫu được mã hóa). Đây là mẫu hoàn chỉnh phù hợp với tôi, sau khi thử nhiều giải pháp.

Tuyên bố miễn trừ trách nhiệm: Mã dưới đây là hỗn hợp các giải pháp được tìm thấy trên liên kết này và một số liên kết stackoverflow khác, cảm ơn thông tin hữu ích.

        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();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.