2009-08-27 7 views
27

Jak określić nazwę użytkownika i hasło do wysyłania żądań Basic-Auth za pomocą usługi App Engine o nazwie URLFetch (w języku Java)?Korzystanie z protokołu HTTP Basic-Auth z aplikacją Google App Engine Usługa URLFetch

Wydaje mogę ustawić nagłówki HTTP:

URL url = new URL("http://www.example.com/comment"); 
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
connection.setRequestProperty("X-MyApp-Version", "2.7.3");   

Jakie są odpowiednie nagłówki Basic Auth?

+1

Czy to naprawdę pytanie dotyczące App Engine? Wystarczy przejrzeć specyfikacje HTTP RFC, aby dowiedzieć się, jak wykonać podstawowe uwierzytelnianie (wskazówka - "autoryzacja"). –

+3

Miałem nadzieję, że może istnieć opakowanie wygody dla App Engine podobne do Apache HttpClient, więc nie muszę ręcznie ustawiać nagłówka autoryzacji (i kodowania base64). – Thilo

+0

Bardzo przydatna informacja –

Odpowiedz

30

Jest to Podstawowy nagłówek auth przez http:

Autoryzacja: Podstawowa kodowana base64 (nazwa użytkownika: hasło)

np

GET /private/index.html HTTP/1.0 
Host: myhost.com 
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== 

Trzeba będzie to zrobić:

URL url = new URL("http://www.example.com/comment"); 
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
connection.setRequestProperty("Authorization", 
"Basic "+codec.encodeBase64String(("username:password").getBytes()); 

I to zrobić będziemy chcieli, aby uzyskać API kodeka base64, jak Apache Commons Codec

+1

Tak właśnie zrobiłem. A ponieważ nazwę użytkownika: hasło wprowadzam jako właściwość w appengine-web.xml, po prostu umieszczam tam kodowaną wersję, więc nie potrzebuję nawet kodeka. (Możesz użyć wiersza poleceń openssl: echo -n "nazwa_użytkownika: hasło" | openssl enc -base64) – Thilo

+0

+1 to również rozwiązało problem, który miałem właśnie z Uwierzytelnieniem HTTP. Dzięki. Och, a getBytes() potrzebuje innego), aby zamknąć setRequestProperty. –

6

skonfigurowaniu Authenticator przed wywołaniem OpenConnection() tak,

Authenticator.setDefault(new Authenticator() { 
    protected PasswordAuthentication getPasswordAuthentication() { 
     return new PasswordAuthentication(username, password.toCharArray()); 
    } 
}); 

Ponieważ istnieje tylko jeden globalny domyślny uwierzytelnienia, to naprawdę nie działa dobrze, gdy masz wielu użytkowników robi się w UrlFetch wiele wątków. Chciałbym użyć Apache HttpClient, jeśli tak jest.

EDYCJA: Myliłem się. App Engine nie zezwala na Authenticator. Nawet jeśli jest to dozwolone, będziemy mieli problem z wieloma wątkami z globalną instancją uwierzytelniającą. Mimo że nie możesz tworzyć wątków, Twoje żądania mogą nadal być wyświetlane w różnych wątkach. Więc po prostu dodać nagłówek ręcznie przy użyciu tej funkcji,

import com.google.appengine.repackaged.com.google.common.util.Base64; 
    /** 
    * Preemptively set the Authorization header to use Basic Auth. 
    * @param connection The HTTP connection 
    * @param username Username 
    * @param password Password 
    */ 
    public static void setBasicAuth(HttpURLConnection connection, 
      String username, String password) { 
     StringBuilder buf = new StringBuilder(username); 
     buf.append(':'); 
     buf.append(password); 
     byte[] bytes = null; 
     try { 
      bytes = buf.toString().getBytes("ISO-8859-1"); 
     } catch (java.io.UnsupportedEncodingException uee) { 
      assert false; 
     } 

     String header = "Basic " + Base64.encode(bytes); 
     connection.setRequestProperty("Authorization", header); 
    } 
+0

W App Engine jest tylko jeden wątek ... (Nawiasem mówiąc, czy jest jakaś dokumentacja, która to gwarantuje?) – Thilo

+0

Mieliśmy problem z tym, myślałem, że to wątkowanie. Sprawdzę z osobą, która to wdrożyła, kiedy w przyszłym tygodniu wrócę do biura. –

+0

Właśnie rozmawiałem z gościem, który przenosił naszą aplikację do Google. Zobacz moje zmiany. –

1

Uwaga na pierwsza odpowiedź: setRequestProperty powinno otrzymać nazwę właściwości bez dwukropka ("Autoryzacja" zamiast "Autoryzacja:").

+0

Przyjemny połów, zredagowałem odpowiedź. –

14

Dla zainteresowanych w ten sposób w Pythonie (jak ja), kod wygląda następująco:

result = urlfetch.fetch("http://www.example.com/comment", 
         headers={"Authorization": 
           "Basic %s" % base64.b64encode("username:pass")}) 
+0

wierzę kod powinien być następujący: wynik = urlfetch.fetch ( „http://yourserver.com/page/init.php, nagłówki = { "Authorization": "Podstawowy% s" % base64 .encodestring ("nazwa_użytkownika: hasło") [: - 1] }); –

+1

Należy użyć: base64.encodestring ("nazwa_użytkownika: hasło"). strip() –

+0

Zaktualizowany do użycia base64.b64.Node Wiem, że działa, ponieważ jest to, co faktycznie używałem w moim prawdziwym kodzie. –

4

Korzystanie HttpURLConnection dał mi pewne problemy (z jakiegoś powodu serwer starałem się połączyć nie zrobił „t akceptuje auth poświadczenia), a na końcu zdałem sobie sprawę, że jest to rzeczywiście dużo łatwiej zrobić przy użyciu GAE za niskiego poziomu UrlFetch API (com.google.appengine.api.urlfetch) tak:

URL fetchurl = new URL(url); 

String nameAndPassword = credentials.get("name")+":"+credentials.get("password"); 
String authorizationString = "Basic " + Base64.encode(nameAndPassword.getBytes()); 

HTTPRequest request = new HTTPRequest(fetchurl); 
request.addHeader(new HTTPHeader("Authorization", authorizationString)); 

HTTPResponse response = URLFetchServiceFactory.getURLFetchService().fetch(request); 
System.out.println(new String(response.getContent())); 

to działało.

+0

To powinna być zaakceptowana odpowiedź, możesz również ustawić limit czasu: FetchOptions fetchOptions = FetchOptions.Builder.withDeadline (10); HTTPRequest req = new HTTPRequest (fetchurl, HTTPMethod.GET, fetchOptions); – ZiglioUK