Android OkHttp with Basic Authentication
Update Code for okhttp3:
import okhttp3.Authenticator;import okhttp3.Credentials;import okhttp3.MediaType;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.Response;import okhttp3.Route;public class NetworkUtil {private final OkHttpClient.Builder client;{ client = new OkHttpClient.Builder(); client.authenticator(new Authenticator() { @Override public Request authenticate(Route route, Response response) throws IOException { if (responseCount(response) >= 3) { return null; // If we've failed 3 times, give up. - in real life, never give up!! } String credential = Credentials.basic("name", "password"); return response.request().newBuilder().header("Authorization", credential).build(); } }); client.connectTimeout(10, TimeUnit.SECONDS); client.writeTimeout(10, TimeUnit.SECONDS); client.readTimeout(30, TimeUnit.SECONDS);}private int responseCount(Response response) { int result = 1; while ((response = response.priorResponse()) != null) { result++; } return result;}}
As pointed out by @agamov:
The aforementioned solution has one drawback: httpClient adds authorization headers only after receiving 401 response
@agamov proposed then to "manually" add authentication headers to each request, but there is a better solution: use an Interceptor
:
import java.io.IOException;import okhttp3.Credentials;import okhttp3.Interceptor;import okhttp3.Request;import okhttp3.Response;public class BasicAuthInterceptor implements Interceptor { private String credentials; public BasicAuthInterceptor(String user, String password) { this.credentials = Credentials.basic(user, password); } @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Request authenticatedRequest = request.newBuilder() .header("Authorization", credentials).build(); return chain.proceed(authenticatedRequest); }}
Then, simply add the interceptor to an OkHttp client that you will be using to make all your authenticated requests:
OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new BasicAuthInterceptor(username, password)) .build();
Here's the updated code:
client.setAuthenticator(new Authenticator() { @Override public Request authenticate(Proxy proxy, Response response) throws IOException { String credential = Credentials.basic("scott", "tiger"); return response.request().newBuilder().header("Authorization", credential).build(); } @Override public Request authenticateProxy(Proxy proxy, Response response) throws IOException { return null; }})