HTTPS-соединение с базовым результатом авторизации в Unauthorized - PullRequest
7 голосов
/ 18 августа 2011

Я пытаюсь получить доступ к Basecamp API из моего исходного кода Android / Java следующим образом ...

import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;

public class BCActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        DefaultHttpClient httpClient = new DefaultHttpClient();

        //final String url = "https://encrypted.google.com/webhp?hl=en"; //This url works
        final String url = "https://username:password@projectsource.basecamphq.com/people.xml"; //This don't
        HttpGet http = new HttpGet(url);
        http.addHeader("Accept", "application/xml");
        http.addHeader("Content-Type", "application/xml"); 

        try {

            //  HttpResponse response = httpClient.execute(httpPost);
            HttpResponse response = httpClient.execute(http);

            StatusLine statusLine = response.getStatusLine();
            System.out.println("statusLine : "+ statusLine.toString()); 

            ResponseHandler <String> res = new BasicResponseHandler();  

            String strResponse = httpClient.execute(http, res);
            System.out.println("________**_________________________\n"+strResponse);
            System.out.println("\n________**_________________________\n");

        } catch (Exception e) {
            e.printStackTrace(); 
        }

        WebView myWebView = (WebView) this.findViewById(R.id.webView);
        myWebView.loadUrl(url);//Here it works and displays XML response

    }
}

Этот URL отображает ответ в WebView, но показываетНесанкционированное исключение при попытке доступа через HttpClient, как показано выше.

Это правильный способ доступа к Basecamp API через Android / Java?или, пожалуйста, предоставьте мне правильный способ сделать это.

Ответы [ 4 ]

10 голосов
/ 18 августа 2011

HttpClient не может получить входные кредиты с URI.
Вы должны дать их указанными методами.

Если вы используете HttpClient 4.x, посмотрите на это:
http://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html

Но обратите внимание, если вы не хотите использовать новую версию на HttpClient (Android использует версию 3.x), вы должны посмотреть здесь:
http://hc.apache.org/httpclient-3.x/authentication.html

Это была теория, теперь мы их используем:
В основном мы используем HTTP , но если вы хотите использовать HTTPS , вам нужно отредактировать следующее назначение new HttpHost("www.google.com", 80, "http") в new HttpHost("www.google.com", 443, "https").

Кроме того, вы должны отредактировать хост ( www.google.com ) для ваших проблем.
Примечание: Требуется только полное доменное имя (FQDN), а не полный URI.

HttpClient 3.x:

package com.test;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.os.Bundle;

public class Test2aActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        try {
            HttpHost targetHost = new HttpHost("www.google.com", 80, "http");

            DefaultHttpClient httpclient = new DefaultHttpClient();
            try {
                // Store the user login
                httpclient.getCredentialsProvider().setCredentials(
                        new AuthScope(targetHost.getHostName(), targetHost.getPort()),
                        new UsernamePasswordCredentials("user", "password"));

                // Create request
                // You can also use the full URI http://www.google.com/
                HttpGet httpget = new HttpGet("/");
                // Execute request
                HttpResponse response = httpclient.execute(targetHost, httpget);

                HttpEntity entity = response.getEntity();
                System.out.println(EntityUtils.toString(entity));
            } finally {
                httpclient.getConnectionManager().shutdown();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

HttpClient 4.x:

Внимание: Вам понадобится новый HttpClient от Apache, и дополнительно вы должны изменить порядок, в котором jar-файл находится перед библиотекой Android.

package com.test;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.os.Bundle;

public class TestActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        try {
            HttpHost targetHost = new HttpHost("www.google.com", 80, "http");

            DefaultHttpClient httpclient = new DefaultHttpClient();
            try {
                // Store the user login
                httpclient.getCredentialsProvider().setCredentials(
                        new AuthScope(targetHost.getHostName(), targetHost.getPort()),
                        new UsernamePasswordCredentials("user", "password"));

                // Create AuthCache instance
                AuthCache authCache = new BasicAuthCache();
                // Generate BASIC scheme object and add it to the local
                // auth cache
                BasicScheme basicAuth = new BasicScheme();
                authCache.put(targetHost, basicAuth);

                // Add AuthCache to the execution context
                BasicHttpContext localcontext = new BasicHttpContext();
                localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);

                // Create request
                // You can also use the full URI http://www.google.com/
                HttpGet httpget = new HttpGet("/");
                // Execute request
                HttpResponse response = httpclient.execute(targetHost, httpget, localcontext);

                HttpEntity entity = response.getEntity();
                System.out.println(EntityUtils.toString(entity));
            } finally {
                httpclient.getConnectionManager().shutdown();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
4 голосов
/ 17 сентября 2013

Приложение о блестящем и очень полезном ответе CSchulz:

в http-клиенте 4.3:

localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);

больше не работает (ClientContext.AUTH_CACHE устарело)

использование:

import org.apache.http.client.protocol.HttpClientContext;

и

localcontext.setAttribute(HttpClientContext.AUTH_CACHE, authCache);

см. http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/protocol/ClientContext.html

и:

http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/protocol/HttpClientContext.html

4 голосов
/ 23 августа 2011

Наконец-то я понял Как склеить код, показанный в ответе выше ...

public static void performPost(String getUri, String xml) {

    String serverName = "*******";
    String username = "*******";
    String password = "********";
    String strResponse = null;

    try {
        HttpHost targetHost = new HttpHost(serverName, 443, "https");

        DefaultHttpClient httpclient = new DefaultHttpClient();
        try {
            // Store the user login
            httpclient.getCredentialsProvider().setCredentials(
                    new AuthScope(targetHost.getHostName(), targetHost.getPort()),
                    new UsernamePasswordCredentials(username, password));

            // Create AuthCache instance
            AuthCache authCache = new BasicAuthCache();
            // Generate BASIC scheme object and add it to the local
            // auth cache
            BasicScheme basicAuth = new BasicScheme();
            authCache.put(targetHost, basicAuth);

            // Add AuthCache to the execution context
            BasicHttpContext localcontext = new BasicHttpContext();
            localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);

            // Create request
            // You can also use the full URI http://www.google.com/
            HttpPost httppost = new HttpPost(getUri);
            StringEntity se = new StringEntity(xml,HTTP.UTF_8);
            se.setContentType("text/xml");
            httppost.setEntity(se); 
            // Execute request
            HttpResponse response = httpclient.execute(targetHost, httppost, localcontext);

            HttpEntity entity = response.getEntity();
            strResponse = EntityUtils.toString(entity);

            StatusLine statusLine = response.getStatusLine();
            Log.i(TAG +": Post","statusLine : "+ statusLine.toString()); 
            Log.i(TAG +": Post","________**_________________________\n"+strResponse);
            Log.i(TAG +": Post","\n________**_________________________\n");

        } finally {
            httpclient.getConnectionManager().shutdown();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

}

Одна очень важная вещь: как должна быть организована ваша библиотека и какие библиотеки вам понадобятся ...

enter image description here

С Здесь вы найдете эти библиотеки.

Чтобы добавить их в Eclipse (ниже Android SDK <16) ... </p>

Project properties -> java build path -> Libraries -> Add external JARs

Упорядочить их по порядку в затмении ...

Project properties -> java build path -> order and export

Для Android выше sdk> = 16 вы должны поместить эти библиотеки в папку "libs".

1 голос
/ 01 сентября 2011

Если вы хотите использовать HttpClient 4.x, как упоминалось в других ответах, вы также можете использовать httpclientandroidlib .Это конвертированный стандартный HttpClient без apache.commons и с поддержкой Android LogCat.

...