2010-10-24 13 views
8

Próbuję połączyć się z serwerem Tomcat Web Server na moim komputerze za pomocą uwierzytelnienia digest. Używam królestwa pamięciowego tomcat. Oto w jaki sposób serwer jest skonfigurowany:Uwierzytelnianie za pomocą HTTP z HttpUrlConnection

1) W server.xml:

<Realm className="org.apache.catalina.realm.MemoryRealm" digest="MD5" /> 

2) w Tomcat-users.xml

<user username="testuser" password="81dc9bdb52d04dc20036dbd8313ed055" roles="test"/> 

3) web.xml mojego internecie projekt:

<auth-method>DIGEST</auth-method> 

jak widać mam określony jako metoda Digest „MD5” i ja zaszyfrowana hasło używając digest.sh Toma kot.

Oto mój kod po stronie klienta:

private static void testGet() throws IOException { 

    // Create a URL 
    URL test = new URL("http://localhost:8080/TestWebProject/TestServlet"); 

    // Open a connection to the URL 
    HttpURLConnection conn = (HttpURLConnection) test.openConnection(); 

    MessageDigest md5 = null; 
    try { 
     md5 = MessageDigest.getInstance("MD5"); 
    } catch(NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 

    // Digest password using the MD5 algorithm 
    String password = "1234"; 
    md5.update(password.getBytes()); 
    String digestedPass = digest2HexString(md5.digest()); 

    // Set header "Authorization" 
    String credentials = "testuser:" + digestedPass; 
    conn.setRequestProperty("Authorization", "Digest " + credentials); 

    // Print status code and message 
    System.out.println("Test HTTP GET method:"); 
    System.out.println("Status code: " + conn.getResponseCode()); 
    System.out.println("Message: " + conn.getResponseMessage()); 
    System.out.println(); 

} 

private static String digest2HexString(byte[] digest) 
{ 
    String digestString=""; 
    int low, hi ; 

    for(int i=0; i < digest.length; i++) 
    { 
     low = (digest[i] & 0x0f) ; 
     hi = ((digest[i] & 0xf0)>>4) ; 
     digestString += Integer.toHexString(hi); 
     digestString += Integer.toHexString(low); 
    } 
    return digestString ; 
} 

myślę, że mój kod po stronie klienta jest ok i konfiguracja serwera, zbyt. Chociaż serwer wysyła do mnie kod statusu 401 z komunikatem "Nieautoryzowane". Ponieważ nie jestem doświadczonym programistą Java, chcę zapytać, czy ktoś ma pomysł lub widzi błąd w mojej implementacji.

Z góry dziękuję!

+0

Generalnie, jeśli strawienia uwierzytelnianie nie jest obowiązkowe, może lepiej byłoby użyć połączenia HTTPS, a niektóre standardowy formularz uwierzytelnianie oparte na HTML, ponieważ uwierzytelnianie HTTP nie obsługuje „Wyloguj się”, aż klient zamknie przeglądarkę internetową. – Kel

+0

Prawdopodobny duplikat [Ulepszone uwierzytelnianie w Androidzie za pomocą HttpURLConnection] (http://stackoverflow.com/questions/32689185/digest-authentication-in-android-using-httpurlconnection) – ceph3us

Odpowiedz

5

Uwierzytelnianie szyfrowane jest znacznie bardziej złożone niż wysyłanie username:password (to jest w rzeczywistości uwierzytelnianie podstawowe ... a krotka username:password musi być zakodowana w Base64!).

Możesz przeczytać wszystko o trawieniu here.

Jeśli nie wymagane do korzystania HttpUrlConnection spojrzeć na tych dwóch projektów:

oboje już wsparcie Digest (i inne przydatne rzeczy) po wyjęciu z pudełka.

2

HttpURLConnection jest OK do prostych zadań, ale jeśli chcesz coś z bardziej zaawansowanych funkcji (jak uwierzytelniania szyfrowanego), polecam Commons HTTP Client.

4

jestem w stanie zrobić to działa następujący kod, proszę dać mi znać jeśli czegoś brakuje;

 DefaultHttpClient httpclient = new DefaultHttpClient(); 

     ResponseHandler<String> responseHandler = new BasicResponseHandler(); 

     httpclient.getCredentialsProvider().setCredentials(
       new AuthScope("localhost", 8080), 
       new UsernamePasswordCredentials("username", "password")); 

     HttpGet httpget = new HttpGet(urlStr); 
     System.out.println("executing request" + httpget.getRequestLine()); 

     String response = httpclient.execute(httpget, responseHandler); 
     System.out.println("Response :: " + response); 
+0

Myślę, że to jest w porządku. Użyłem prawie tego samego kodu. – user485624

+0

DefaultHttpClient w obecnie przestarzałym i HttpClient nie ma już metody getCredentialsProvider ...czy ktoś ma zaktualizowany przykład? – Rafael

+0

To zadziałało dla mnie. Dzięki! – basari66

3

Użyj następującego kodu, działa.

import org.apache.http.auth.UsernamePasswordCredentials; 
import org.apache.http.client.CredentialsProvider; 
import org.apache.http.impl.client.CloseableHttpClient; 

CredentialsProvider credsProvider = new BasicCredentialsProvider(); 
     credsProvider.setCredentials(
       new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), 
       new UsernamePasswordCredentials(username, password)); 
     CloseableHttpClient httpclient = HttpClients.custom() 
       .setDefaultCredentialsProvider(credsProvider) 
       .build(); 


HttpResponse response = httpClient.execute(get); 
+4

Kontekst i wyjaśnienie byłyby pomocne dla przyszłych użytkowników, którzy natkną się na tę odpowiedź, mając ten sam problem – StormeHawke

Powiązane problemy