2

Я собираюсь использовать службу, использующую аутентификацию на предъявителя. Я пытался получить его от Android напрасно. Вот мой код.Как получить доступ к службе удостоверения подлинности на предъявителя с Android

String mytoken = "some token I am sure is right"; 
HttpClient witClient = new DefaultHttpClient(); 
Uri.Builder b = Uri.parse("www.somewebsite.com").buildUpon(); 
b.appendQueryParameter("q", "some query string"); 
String finalurl = b.build().toString(); 
HttpGet request = new HttpGet(new URI(finalurl)); 
request.setHeader("Authorization", "Bearer "+mytoken); 
HttpResponse response = witClient.execute(request); 

Сервер вернет мне сообщение об ошибке, требующей аутентификации. Очевидно, что заголовок как-то отбрасывается.

11-22 21:50:42.180: W/DefaultRequestDirector(3408): Authentication error: Unable to respond to any of these challenges: {bearer=Www-Authenticate: Bearer realm="OAuth required"} 

где неправильно

ответ

4

Это может быть немного сложным, но я имел успех с ним, так что я постараюсь дать вам преимущество моего опыта.

Вы должны предоставить несколько пунктов

  • реализация org.apache.http.auth.Credentials
  • Реализация org.apache.http.auth.AuthSchemeFactory

Реализация ваших учетных данных должна быть примерно такой, как:

import java.security.Principal; 

import org.apache.http.auth.BasicUserPrincipal; 
import org.apache.http.auth.Credentials; 

public class TokenCredentials implements Credentials { 
    private Principal userPrincipal; 

    public TokenCredentials(String token) { 
     this.userPrincipal = new BasicUserPrincipal(token); 
    } 

    @Override 
    public Principal getUserPrincipal() { 
     return userPrincipal; 
    } 

    @Override 
    public String getPassword() { 
     return null; 
    } 

} 

Тогда вам нужно реализовать AuthSchemeFactory:

import org.apache.http.Header; 
import org.apache.http.HttpRequest; 
import org.apache.http.auth.AUTH; 
import org.apache.http.auth.AuthScheme; 
import org.apache.http.auth.AuthSchemeFactory; 
import org.apache.http.auth.AuthenticationException; 
import org.apache.http.auth.ContextAwareAuthScheme; 
import org.apache.http.auth.Credentials; 
import org.apache.http.auth.MalformedChallengeException; 
import org.apache.http.message.BufferedHeader; 
import org.apache.http.params.HttpParams; 
import org.apache.http.protocol.HttpContext; 
import org.apache.http.util.CharArrayBuffer; 

public class BearerAuthSchemeFactory implements AuthSchemeFactory { 

    @Override 
    public AuthScheme newInstance(HttpParams params) { 
     return new BearerAuthScheme(); 
    } 

    private static class BearerAuthScheme implements ContextAwareAuthScheme { 
     private boolean complete = false; 

     @Override 
     public void processChallenge(Header header) throws MalformedChallengeException { 
      this.complete = true; 
     } 

     @Override 
     public Header authenticate(Credentials credentials, HttpRequest request) throws AuthenticationException { 
      return authenticate(credentials, request, null); 
     } 

     @Override 
     public Header authenticate(Credentials credentials, HttpRequest request, HttpContext httpContext) 
       throws AuthenticationException { 
      CharArrayBuffer buffer = new CharArrayBuffer(32); 
      buffer.append(AUTH.WWW_AUTH_RESP); 
      buffer.append(": Bearer "); 
      buffer.append(credentials.getUserPrincipal().getName()); 
      return new BufferedHeader(buffer); 
     } 

     @Override 
     public String getSchemeName() { 
      return "Bearer"; 
     } 

     @Override 
     public String getParameter(String name) { 
      return null; 
     } 

     @Override 
     public String getRealm() { 
      return null; 
     } 

     @Override 
     public boolean isConnectionBased() { 
      return false; 
     } 

     @Override 
     public boolean isComplete() { 
      return this.complete; 
     } 
    } 
} 

Следующим шагом становится HttpClient, чтобы принять его в качестве действительного схеме:

HttpContext httpContext = new BasicHttpContext(); 

    AuthSchemeRegistry authSchemeRegistry = new AuthSchemeRegistry(); 
    authSchemeRegistry.register("Bearer", new BearerAuthSchemeFactory()); 
    httpContext.setAttribute(ClientContext.AUTHSCHEME_REGISTRY, authSchemeRegistry); 
    AuthScope sessionScope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, "Bearer"); 

    Credentials credentials = new TokenCredentials (token); 
    CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); 
    credentialsProvider.setCredentials(sessionScope, credentials); 
    httpContext.setAttribute(ClientContext.CREDS_PROVIDER, credentialsProvider); 

Я обычно будет создавать эти для каждого контекста основе и подвесить на к контексту в течение определенного периода времени.

Дополнительная документация может быть найдена here. Я бы рекомендовал держаться подальше от «упреждающей» аутентификации и позволить мастерству делать свою работу в решении проблемы 401.

Если вы хотите узнать, о чем я говорю, включите ведение журнала в HTTP-клиенте, чтобы вы могли отслеживать цепочку разговоров - вы увидите, что первоначальный запрос возвращается с вызовом, а затем клиент будет использовать поставщик учетных данных для поиска соответствующих учетных данных и отправки запроса с соответствующим ответом на вызов для схемы, которую мы определили.

Удачи вам!

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