2013-02-27 2 views
2

Я пытаюсь пройти аутентификацию с веб-сайта. Я использую AsyncHttpClient. Вот код, который я пытаюсь.Ошибка аутентификации AsyncHttpClient

Вот мой код,

public class LoginActivity extends Activity { 

    String tag = "LoginActivity"; 
    Button requestBtn; 
    AsyncHttpClient httpClient = new AsyncHttpClient(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_login); 

     requestBtn = (Button) findViewById(R.id.upload_file); 

     PersistentCookieStore myCookieStore = new PersistentCookieStore(this); 
     httpClient.setCookieStore(myCookieStore); 

     httpClient.setBasicAuth(ApplicationConstants.userName, 
       ApplicationConstants.password, new AuthScope(
         "http://*.*.*.*:8080/someUrl", 8080, 
         AuthScope.ANY_REALM)); 




     requestBtn.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
     httpClient.get("http://*.*.*.*:8080/someurl",new AsyncHttpResponseHandler() { 

       @Override 
       public void onSuccess(String response) { 
       System.out.println(response); 
       Log.d("Sucessful upload","Onsucess" + response); 
       } 

       @Override 
       public void onFailure(Throwable arg0,String arg1) { 

       Log.d("LoginActivity",arg0.toString()); 
       arg0.printStackTrace(); 
       super.onFailure(arg0, arg1); 
       } 
      }); 
     } 

    } 
    }); 
} 
} 

я получаю исключение, когда я нажимаю на кнопку. Он говорит Ошибка аутентификации Исключение Logcat:

02-27 16:02:42.930: D/LoginActivity(8869): org.apache.http.client.HttpResponseException: Unauthorized 
02-27 16:02:42.930: W/System.err(8869): org.apache.http.client.HttpResponseException: Unauthorized 
02-27 16:02:42.930: W/System.err(8869):  at com.loopj.android.http.AsyncHttpResponseHandler.sendResponseMessage(AsyncHttpResponseHandler.java:235) 
02-27 16:02:42.930: W/System.err(8869):  at com.loopj.android.http.AsyncHttpRequest.makeRequest(AsyncHttpRequest.java:79) 
02-27 16:02:42.930: W/System.err(8869):  at com.loopj.android.http.AsyncHttpRequest.makeRequestWithRetries(AsyncHttpRequest.java:95) 
02-27 16:02:42.930: W/System.err(8869):  at com.loopj.android.http.AsyncHttpRequest.run(AsyncHttpRequest.java:57) 
02-27 16:02:42.930: W/System.err(8869):  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442) 
02-27 16:02:42.930: W/System.err(8869):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
02-27 16:02:42.930: W/System.err(8869):  at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
02-27 16:02:42.940: W/System.err(8869):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
02-27 16:02:42.940: W/System.err(8869):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
02-27 16:02:42.940: W/System.err(8869):  at java.lang.Thread.run(Thread.java:856) 

Что не так я делаю? Правильный URL, который я использую.

+0

Похоже, что пользователь/пароль неверен. – m0skit0

+0

Когда я нажимаю те же учетные данные в своем браузере, он отлично работает –

+0

Вы видели, что 'httpClient.get (" http: //*.*.*.*: 8080someurl "' отличается от нового AuthScope ("http://*.*.*.*: 8080/someUrl "'. Вы должны использовать константы для таких строк. – m0skit0

ответ

5

От Basic Authentication with Android:

Android отгружает с апача HttpClient 4,0 Beta2, который имеет ловушку, когда речь идет о базовой аутентификации.

При поиске HttpClient и базовой аутентификации Google, безусловно, отправит вас в официальную документацию HttpClient 3.x, в которой показано, как выполнить базовую аутентификацию в preemptive way. Это означает, что вы отправляете учетные данные клиента с каждым запросом, а не ожидаете неавторизованного ответа 401 и только затем отправляете учетные данные. Вероятно, это именно то, что вы хотите, в первую очередь, потому что это сохраняет ваш клиент в запросе.

HttpClient client = new HttpClient(); 
client.getParams().setAuthenticationPreemptive(true); 
Credentials defaultcreds = new UsernamePasswordCredentials("username", "password"); 
client.getState().setCredentials(new AuthScope("myhost", 80, AuthScope.ANY_REALM), defaultcreds); 

Этот пример кода не компилировать с HttpClient версии 4. Метод называется setAuthenticationPreemptive отсутствует. Проблема в том, что если вы опускаете этот вызов метода, код все еще работает, но аутентификация не является превентивной. Мы пропустили эту небольшую деталь и заметили через некоторое время, что каждому запросу предшествовал 401 Несанкционированный цикл запроса/ответа. Это удвоило количество запросов, которые мы обслуживали.

Теперь проверьте выполнение AsyncHttpClient:

private final DefaultHttpClient httpClient; 
public void setBasicAuth(String user, String pass, AuthScope scope){ 
    UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(user,pass); 
    this.httpClient.getCredentialsProvider().setCredentials(scope, credentials); 
} 

Так что я думаю, loopj может также столкнуться с проблемой использования старого HttpClient 3.x способ сделать обычную проверку подлинности. Он действительно работает, но он не превентивный.

Простое решение будет загружать исходный код loopj и изменять его источник и использовать модифицированную версию.

Изменение в коде будет:

httpClient.setBasicAuth(ApplicationConstants.userName, 
      ApplicationConstants.password); 

вместо

  httpClient.setBasicAuth(ApplicationConstants.userName, 
      ApplicationConstants.password, new AuthScope(
        "http://*.*.*.*:8080/uploadservice", 80, 
        AuthScope.ANY_REALM)); 
+0

Спасибо большое !! Выполняем некоторые работы, и я приму свой ответ –

+0

Спасибо за ваше редактирование. – StarPinkER

4

Я думаю, вы можете решить эту проблему путем явного добавления заголовка, который обрабатывать Basic Auth.

Context context = this; 
String url = "http://*.*.*.*:8080/someurl"; 

UsernamePasswordCredentials credentials = 
new UsernamePasswordCredentials(ApplicationConstants.userName, 
      ApplicationConstants.password); 

Header header = BasicScheme.authenticate(credentials, "UTF-8", false); 

Header[] headers = {header}; 

RequestParams params = new RequestParams(); 

httpClient.get(context, url, headers, params, new AsyncHttpResponseHandler(){ .. 

Также не забудьте переопределить метод «OnComplete», а если вы хотите узнать, что ответ сервера. Потому что в случае исключения он не может пройти через «onSuccess» и «onFailure».

+0

не пошел с потоком моего приложения, но все же тому назад od предложение –

+0

Это сработало для меня, спасибо. Вопреки объяснениям выше, базовая аутентификация вообще не работала с использованием только loopj. – Alex

+0

Молодцы. :) .. – AAnkit

11

Я придумал другое решение, потому что у меня были проблемы с промежуточными прокси-серверами, которым не нравилось, как заголовок авторизации была построена с использованием вышеуказанного предлагаемого решения, а также по умолчанию (ошибка) setBasicAuth(username, password) реализации AsyncHttpClient.

Итак, я добавил заголовок сам, самостоятельно используя кодировку имени пользователя и пароля BASE64, но используя метод addHeader(), унаследованный от реализации родительского клиента.

Это работает сейчас.

asyncHttpClient.addHeader(
    "Authorization", 
    "Basic " + Base64.encodeToString(
     (username+":"+password).getBytes(),Base64.NO_WRAP) 
); 

Я надеюсь, что это поможет кому-то.

+0

Сладкий и короткий! Спасибо за это много лет, спасибо человеку! – Chris

+0

Удивительный! Вы спасли меня неделю работы. Я полностью согласен с вами в том, что метод setBasicAuth - это мусор. – technik

Смежные вопросы