HttpWebRequest โดยใช้การรับรองความถูกต้องเบื้องต้น


139

ฉันพยายามที่จะผ่านการร้องขอการรับรองความถูกต้องที่เลียนแบบ "การรับรองความถูกต้องขั้นพื้นฐาน" เราเคยเห็นเมื่อตั้งค่า IIS สำหรับพฤติกรรมนี้

URL คือ: 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;
bpeikes

คำตอบ:


277

คุณสามารถเพิ่มส่วนหัวการอนุญาตด้วยตัวเอง

เพียงตั้งชื่อ "การอนุญาต" และค่า "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);

แก้ไข

เปลี่ยนการเข้ารหัสจาก UTF-8 เป็น ISO 8859-1 ต่อการเข้ารหัสใดที่ฉันควรใช้สำหรับการตรวจสอบสิทธิ์พื้นฐาน HTTP และความคิดเห็นของ Jeroen


3
แล้วคุณจะรู้ได้อย่างไรว่า UTF8 นั้นเป็นการเข้ารหัสที่ถูกต้องที่จะใช้?
Jeroen Wiert Pluimers

2
รับได้สวย. ดูเหมือนว่าส่วนหัวการรับรองความถูกต้องควรเข้ารหัสใน ISO-8859-1 ต่อstackoverflow.com/questions/7242316/…
Zambonilli

1
Aaaargh! 1: ขอบคุณเพื่อน 2. ฉันอยากจะเข้าใจว่าทำไมวิธีอื่น ๆ ตั้งค่าวิธีการรับรองความถูกต้องใน CredentialCache จะไม่ทำงานเลย พวกเขาควรจะใช่มั้ย
mshthn

1
เอกสารคู่มือ msdn ทั้งหมดชี้ไปที่ใช่วิธีอื่นควรใช้งานได้ อย่างไรก็ตามฉันไม่สามารถทำให้พวกเขาทำงานได้
Zambonilli

ไม่ทำงานสำหรับฉัน (ไม่ใช่ utf-8 หรือ ISO-8859-1) ข้อเสนอแนะสิ่งที่จะตรวจสอบ? มันทำงานได้เมื่อฉันทำ "webRequest.Credentials = ใหม่ NetworkCredential (UserID, รหัสผ่าน);" .
RollerCosta

56

ในที่สุดฉันก็รับมัน!

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

เย้!


29

ถ้าคุณสามารถใช้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");

8

ลองสิ่งนี้:

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; 

มันรับรองความถูกต้องพื้นฐานอย่างแน่นอน? นอกจากนี้คุณสามารถเข้าถึงทรัพยากรด้วยชื่อผู้ใช้ / รหัสผ่านของคุณผ่านเบราว์เซอร์ได้หรือไม่?
MrEyes

ดูเหมือนว่าจะเป็นการตรวจสอบขั้นพื้นฐานมากกว่า https หากคุณคลิกที่ลิงก์ที่ฉันให้ไว้เบราว์เซอร์จะขอชื่อผู้ใช้ / รหัสผ่าน "ป๊อปอัป" เช่นเดียวกับเมื่อคุณทำ "การตรวจสอบขั้นพื้นฐาน" ใน IIS หรือใช้ไฟล์. htaccss ในโฟลเดอร์ผ่าน apache ฉันพยายามใช้พู้ทำเล่น ฉันไม่มีเงื่อนงำใด ๆ เลย
Kenny Rullo

ฉันเพิ่งรู้ว่าเว็บไซต์กำลังทำงานภายใต้เซิร์ฟเวอร์ IBM http นี่อาจเป็นข่าวที่มีประโยชน์หรือ
Kenny Rullo

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;

3

รหัสต่อไปนี้จะแก้ปัญหาการตอบสนอง json ถ้ามีการรับรองความถูกต้องขั้นพื้นฐานและพร็อกซี่ดำเนินการนอกจากนี้ IIS 7.5 โฮสติ้ง 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 = ใหม่ NetworkCredential (ID ผู้ใช้รหัสผ่าน);"
RollerCosta

2

ข้อมูลจำเพาะสามารถอ่านได้ว่า "ISO-8859-1" หรือ "undefined" ทางเลือกของคุณ. เป็นที่ทราบกันดีว่าเซิร์ฟเวอร์หลายเครื่องใช้ ISO-8859-1 (ถูกใจหรือไม่) และจะล้มเหลวเมื่อคุณส่งสิ่งอื่น

สำหรับข้อมูลเพิ่มเติมและข้อเสนอเพื่อแก้ไขสถานการณ์ดูhttp://greenbytes.de/tech/webdav/draft-reschke-basicauth-enc-latest.html


1

การก่อสร้างต่อไปนี้ทำงานไม่ถูกต้องสำหรับฉัน:

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

ฉันหวังว่ามันจะช่วยให้ใครบางคนในอนาคต


0

สิ่งแรกสำหรับฉัน ServicePointManager.SecurityProtocol = SecurityProtocolType Tls12ทำงานแทน Ssl3

ประการที่สองฉันต้องส่งคำขอตรวจสอบขั้นพื้นฐานพร้อมกับข้อมูลบางอย่าง (ฟอร์ม - urlencoded) นี่คือตัวอย่างที่สมบูรณ์ซึ่งใช้ได้กับฉันอย่างสมบูรณ์แบบหลังจากลองใช้วิธีแก้ปัญหามากมาย

ข้อจำกัดความรับผิดชอบ: รหัสด้านล่างนี้เป็นส่วนผสมของโซลูชั่นที่พบในลิงค์นี้และลิงค์อื่น ๆ ของสแต็คโอเวอร์โฟลว์ขอบคุณสำหรับข้อมูลที่มีประโยชน์

        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();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.