OkHttp源码学习之Authenticator

305 阅读2分钟

OkHttp 中,Authenticator 接口用于处理认证挑战。当服务器返回 401 (Unauthorized) 或代理服务器返回 407 (Proxy Authentication Required) 时,Authenticator 会被调用来生成一个合适的认证请求(如添加必要的认证信息)。

其主要作用是实现自动化的身份认证,而不需要每次手动处理。典型的应用场景包括:

  • 处理 HTTP 基本认证 (Basic Authentication)。
    • Preemptive Authentication(主动认证)
    • Reactive Authentication(被动认证)
  • 处理 OAuth Token 刷新
  • 与代理服务器交互时提供认证信息。

使用示例

以下是一个简单的 Basic Authentication 示例(Reactive Authentication):

OkHttpClient client = new OkHttpClient.Builder()
    .authenticator(new Authenticator() {
        @Override
        public Request authenticate(Route route, Response response) {
            String credential = Credentials.basic("username", "password");
            return response.request().newBuilder()
                .header("Authorization", credential)
                .build();
        }
    })
    .build();

以下是一个简单的 在 OkHttp 中实现 Preemptive Authentication:

OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(chain -> {
        Request request = chain.request()
            .newBuilder()
            .header("Authorization", Credentials.basic("username", "password"))
            .build();
        return chain.proceed(request);
    })
    .build();

Reactive vs Preemptive 的比较

特性Reactive AuthenticationPreemptive Authentication
发送时机接收到挑战后发送请求初始阶段主动发送
性能延迟较高,需多一次往返延迟较低,无需等待挑战
安全性较高,仅在需要时发送较低,认证信息总是发送
实现复杂性需要额外处理重试逻辑简单,无需处理重试
典型场景非敏感服务,挑战后认证高性能服务或可信环境下的认证

总结

核心方法

Authenticator 是一个接口,定义了以下方法:

Request authenticate(Route route, Response response) throws IOException;

参数

  • route: 表示连接的路由信息,包含主机地址等。
  • response: 表示需要认证的响应对象,包含了挑战信息(如 WWW-AuthenticateProxy-Authenticate 头部)。

返回值

  • 返回一个包含认证信息的新 Request 对象。
  • 如果返回 null,OkHttp 将认为认证失败,不会尝试进一步的请求。