2009-11-09 15 views
31

Próbuję użyć HTTPWebRequest, aby uzyskać dostęp do usługi REST i mam problemy z przekazaniem poświadczeń, zobacz poniższy kod. Czytałem, że NetworkCredential nie obsługuje SSL i trafiam na stronę HTTPS. Czy ktoś wie o klasie podobnej do NetworkCredential, która obsługuje SSL?HttpWebRequest nie przekazuje poświadczeń

Uri requestUri = null; 
Uri.TryCreate("https://mywebserver/webpage", UriKind.Absolute, out requestUri); 
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(requestUri); 
NetworkCredential nc = new NetworkCredential("user", "password"); 
request.Credentials = nc; 
request.Method = WebRequestMethods.Http.Get; 
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

Odpowiedz

20

Jeśli serwer używa uwierzytelniania NTLM można spróbować to:

CredentialCache cc = new CredentialCache(); 
cc.Add(
    new Uri("https://mywebserver/webpage"), 
    "NTLM", 
    new NetworkCredential("user", "password")); 
request.Credentials = cc; 
+0

Ten pracował dla ja, dzięki. –

3

Spróbuj ustawić request.PreAuthenticate true.

+1

Według [this] (http://weblog.west-wind.com/posts/2010/Feb/18/NET-WebRequestPreAuthenticate-not-quite-what-it-sounds-like) to nie zadziała. Nadal wymaga trochę pracy. – chaZm

25

Jaki mechanizm uwierzytelniania chroni serwis internetowy? Poświadczenia ustawione na HttpWebRequest będą przekazywane tylko przez nagłówek HTTP Authorization przez Basic, Digest lub NTLM. Tak więc, jeśli twoja usługa internetowa jest chroniona przez WS-Security, prawdopodobnie NetworkCredentials nie zostanie w ogóle przekazany do schematu uwierzytelniania, ponieważ WS-Security nie działa na poziomie HTTP.

Co należy zrobić, to utworzyć proxy klienta usług sieci Web dla usługi WWW za pomocą narzędzia wiersza polecenia wsdl.exe lub czegoś podobnego. Umożliwi to dostęp do świadomych schematów uwierzytelniania usługi Web Service.

Aktualizacja po komentarzach:

Wydaje się HttpWebRequest potrzeb otrzymywać wyzwanie WWW-Authenticate z 401 Unauthorized zanim może uwierzytelnić właściwie przez SSL. Domyślam się, że istnieją dwie oddzielne ścieżki kodu w HttpWebRequests obsługujące zwykły ruch HTTP i szyfrowany ruch HTTPS. W każdym razie, co należy spróbować, to:

  1. Execute nieuwierzytelnionego HttpWebRequest do https://.../ URI.
  2. Otrzymaj odpowiedź 401 Unauthorized.
  3. Wykonaj to samo żądanie, teraz z zestawem Credentials (nie jestem pewien, czy PreAuthenticate powinien być true lub false, przetestuj oba).
  4. Powinieneś teraz uzyskać 200 OK lub cokolwiek odpowiada na twoją usługę sieciową.

Inną opcją jest stworzenie nagłówka Authorization się na początkowym życzenie:

string credentials = String.Format("{0}:{1}", username, password); 
byte[] bytes = Encoding.ASCII.GetBytes(credentials); 
string base64 = Convert.ToBase64String(bytes); 
string authorization = String.Concat("Basic ", base64); 
request.Headers.Add("Authorization", authorization); 
+0

Niestety, nie zdawałem sobie sprawy, że do tej pory jest to usługa REST, do której dzwonię, więc istnieje teraz plik wsdl. Ponadto, jestem w stanie przejść kod w debugerze i widzę, że prawidłowo buduje on obiekt NetworkCredentials, ale po prostu nie wydaje się, że zostanie przekazany za pomocą HttpWebRequest. Jeszcze jedno - mogę z powodzeniem wywołać usługę REST, wpisując ją w pasku adresu przeglądarki, więc musi ona używać moich danych uwierzytelniających w ten sposób. –

+1

Nie napisałeś, jakiego schematu uwierzytelniania używasz i skąd masz dane uwierzytelniające. Dodatkowo, jeśli jest to usługa REST, nie powinien mieć pliku WSDL. Usługa sieci Web z plikiem WSDL jest zwykle usługą sieciową SOAP, która jest przeciwieństwem usługi sieciowej REST. Czy można uzyskać dostęp do usługi sieci Web za pomocą przeglądarki (bez wpisywania jakichkolwiek poświadczeń?) Brzmi, jakby był chroniony za pomocą uwierzytelniania HTTP, prawdopodobnie NTLM. Czy to prawda? –

+0

Jaką odpowiedź otrzymasz? Czy jest to "401 Nieautoryzowane", "403 Zabronione" czy coś innego? –

48

Zobacz, czy pokazuje się podczas korzystania z staroświeckie metody:

string credentials = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes("user"+ ":" + "password")); 
request.Headers.Add("Authorization", "Basic " + credentials); 
+0

to właśnie dla mnie zadziałało. – ryancammer

+0

po prostu pracował dla mnie. – SouthShoreAK

+0

Rozwiązałem mój problem. Wzniesiono go z powodu jego zwięzłości. – Skitterm