OkHttp重定向时保留Authorization头:自定义策略实现问询
OkHttp默认会在跨协议、主机或端口的重定向请求中移除Authorization头,如果你需要在特定可信域的重定向中保留这类安全头,以下是几种可行的实现思路,适配SDK场景的通用扩展需求:
方案一:通过网络拦截器干预重定向请求
网络拦截器可以捕获OkHttp发起的所有请求(包括自动生成的重定向请求),适合在不修改OkHttp默认重定向逻辑的前提下,按需添加安全头。
实现步骤
- 定义拦截器,通过
priorResponse()判断当前请求是否为重定向请求,结合自定义回调判断重定向目标是否属于可信域。 - 若符合条件,从原始请求中取出Authorization头,添加到重定向请求中。
代码示例
public class TrustedDomainAuthInterceptor implements Interceptor { private final Predicate<HttpUrl> trustedDomainChecker; // 传入用户自定义的可信域判断逻辑 public TrustedDomainAuthInterceptor(Predicate<HttpUrl> trustedDomainChecker) { this.trustedDomainChecker = trustedDomainChecker; } @Override public Response intercept(Chain chain) throws IOException { Request currentRequest = chain.request(); Response priorResponse = currentRequest.priorResponse(); // 判定当前请求是重定向请求 if (priorResponse != null) { Request originalRequest = priorResponse.request(); String authHeader = originalRequest.header("Authorization"); // 原始请求带Authorization头,且重定向目标是可信域 if (authHeader != null && trustedDomainChecker.test(currentRequest.url())) { // 重构建请求并添加Authorization头 Request modifiedRequest = currentRequest.newBuilder() .header("Authorization", authHeader) .build(); return chain.proceed(modifiedRequest); } } return chain.proceed(currentRequest); } }
集成到SDK
在SDK内部构建OkHttpClient时,添加该拦截器,并开放钩子让用户注入可信域判断逻辑:
// SDK配置类开放回调设置 public class SDKConfiguration { private Predicate<HttpUrl> redirectTrustedDomainPredicate = (url) -> { // 默认行为:与OkHttp一致,仅同域保留头 Request originalRequest = ...; // 获取原始请求 HttpUrl originalUrl = originalRequest.url(); return originalUrl.scheme().equals(url.scheme()) && originalUrl.host().equals(url.host()) && originalUrl.port() == url.port(); }; public void setRedirectTrustedDomainPredicate(Predicate<HttpUrl> predicate) { this.redirectTrustedDomainPredicate = predicate; } } // SDK内部构建OkHttpClient OkHttpClient client = new OkHttpClient.Builder() .addNetworkInterceptor(new TrustedDomainAuthInterceptor(config.getRedirectTrustedDomainPredicate())) .build();
方案二:手动接管重定向逻辑(完全自定义)
如果需要更彻底的控制,可以禁用OkHttp自动重定向,通过应用拦截器手动处理重定向响应,完全控制请求头的转发规则。
实现步骤
- 禁用OkHttp的自动重定向(
followRedirects(false))。 - 应用拦截器捕获重定向响应(3xx状态码),解析Location头构建新请求。
- 通过用户回调判断是否转发Authorization头,手动执行重定向请求。
代码示例
public class CustomRedirectInterceptor implements Interceptor { private final BiPredicate<HttpUrl, HttpUrl> shouldForwardAuth; // 传入原始URL与重定向URL的判断逻辑 public CustomRedirectInterceptor(BiPredicate<HttpUrl, HttpUrl> shouldForwardAuth) { this.shouldForwardAuth = shouldForwardAuth; } @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); Response response = chain.proceed(originalRequest); // 处理重定向响应 if (response.isRedirect()) { String location = response.header("Location"); if (location == null) return response; HttpUrl originalUrl = originalRequest.url(); HttpUrl redirectUrl = originalUrl.resolve(location); if (redirectUrl == null) return response; Request.Builder redirectReqBuilder = originalRequest.newBuilder().url(redirectUrl); // 根据回调决定是否保留Authorization头 if (shouldForwardAuth.test(originalUrl, redirectUrl)) { String authHeader = originalRequest.header("Authorization"); if (authHeader != null) { redirectReqBuilder.header("Authorization", authHeader); } } else { redirectReqBuilder.removeHeader("Authorization"); } // 手动发起重定向请求 return chain.proceed(redirectReqBuilder.build()); } return response; } }
集成到SDK
OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new CustomRedirectInterceptor((originalUrl, redirectUrl) -> { // 用户自定义判断逻辑,例如匹配可信域名后缀 return redirectUrl.host().endsWith(".ibm.com"); })) .followRedirects(false) // 禁用自动重定向 .build();
关键注意事项
- 若需要转发除Authorization外的其他安全头(如Cookie),可扩展拦截器逻辑,添加头列表的配置项。
- 网络拦截器方案更轻量,无需修改OkHttp默认行为;手动接管方案则提供最完整的控制权。
- 回调逻辑需考虑安全性,避免将敏感头转发到不可信域。
内容的提问来源于stack exchange,提问作者Phil Adams
相关产品推荐
相关产品推荐

