Мне удалось использовать дайджест-проверку подлинности с использованием OkHttp . В этом примере кода я также использую Dagger и Robospice-retrofit. Я создал OkHttp Authenticator и назначил его своему клиенту OkHttp.
Класс authenticator реализует метод authenticate , который будет вызываться всякий раз, когда сервер обнаружит ошибку 401 и ожидает Authorization back header (если он ожидает Proxy-Authorization Вы должны реализовать метод authenticateProxy .
Что он в основном делает, так это оборачивает вызовы в HttpClient DigestScheme и делает его пригодным для OkHttp. В настоящее время это не увеличивает счетчик nc. Это может вызвать проблемы с вашим сервером, так как это может быть интерпретировано как атака воспроизведения.
public class DigestAuthenticator implements com.squareup.okhttp.Authenticator {
@Inject DigestScheme mDigestScheme;
@Inject org.apache.http.auth.Credentials mCredentials;
@Override
public Request authenticate(Proxy proxy, Response response) throws IOException {
String authHeader = buildAuthorizationHeader(response);
if (authHeader == null) {
return null;
}
return response.request().newBuilder().addHeader("Authorization", authHeader).build();
}
@Override
public Request authenticateProxy(Proxy proxy, Response response) throws IOException {
return null;
}
private String buildAuthorizationHeader(Response response) throws IOException {
processChallenge("WWW-Authenticate", response.header("WWW-Authenticate"));
return generateDigestHeader(response);
}
private void processChallenge(String headerName, String headerValue) {
try {
mDigestScheme.processChallenge(new BasicHeader(headerName, headerValue));
} catch (MalformedChallengeException e) {
Timber.e(e, "Error processing header " + headerName + " for DIGEST authentication.");
}
}
private String generateDigestHeader(Response response) throws IOException {
org.apache.http.HttpRequest request = new BasicHttpRequest(
response.request().method(),
response.request().uri().toString()
);
try {
return mDigestScheme.authenticate(mCredentials, request).getValue();
} catch (AuthenticationException e) {
Timber.e(e, "Error generating DIGEST auth header.");
return null;
}
}
}
Затем аутентификатор будет использоваться в OkHttpClient, созданном с провайдером:
public class CustomClientProvider implements Client.Provider {
@Inject DigestAuthenticator mDigestAuthenticator;
@Override
public Client get() {
OkHttpClient client = new OkHttpClient();
client.setAuthenticator(mDigestAuthenticator);
return new OkClient(client);
}
}
Наконец, клиент настроен на сервер RetrofitRobospice в функции createRestAdapterBuilder :
public class ApiRetrofitSpiceService extends RetrofitJackson2SpiceService {
@Inject Client.Provider mClientProvider;
@Override
public void onCreate() {
App.get(this).inject(this);
super.onCreate();
addRetrofitInterface(NotificationRestInterface.class);
}
@Override
protected String getServerUrl() {
return Constants.Url.BASE;
}
@Override
protected RestAdapter.Builder createRestAdapterBuilder() {
return super.createRestAdapterBuilder()
.setClient(mClientProvider.get());
}
}