gpt4 book ai didi

Android - 为 Digest Auth 配置 Retrofit/Apache HttpClient

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:49:52 24 4
gpt4 key购买 nike

我正在开发一个 Android 项目并尝试让摘要式身份验证与 Retrofit 一起使用。我有点惊讶 Retrofit 本身不支持它(或者更准确地说,OkHttp 不支持它),但我想提示没有意义。

我在这里浏览了很多线程,看来正确的解决方案是将 Apache HttpClient(它本身支持 Digest Auth)与 Retrofit 集成。这需要使用 retrofit.client.Client 实现包装 HttpClient。 Retrofit 传入的值必须被解析并构建到一个新的 HttpClient 响应中,然后将其发送回 Retrofit 以进行正常处理。感谢 Jason Tu 和他的例子:https://gist.github.com/nucleartide/24628083decb65a4562c

问题是,它不起作用。我每次都收到 401 Unauthorized 消息,我不清楚原因。这是我的客户暗示:

public class AuthClientRedirector implements Client {
private final CloseableHttpClient delegate;

public AuthClientRedirector(String user, String pass, String hostname, String scope) {
Credentials credentials = new UsernamePasswordCredentials(user, pass);
AuthScope authScope = new AuthScope(hostname, 443, scope);

CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(authScope, credentials);

delegate = HttpClientBuilder.create()
.setDefaultCredentialsProvider(credentialsProvider)
.build();
}

@Override
public Response execute(Request request) {
//
// We're getting a Retrofit request, but we need to execute an Apache
// HttpUriRequest instead. Use the info in the Retrofit request to create
// an Apache HttpUriRequest.
//
String method = request.getMethod();

ByteArrayOutputStream bos = new ByteArrayOutputStream();
if (request.getBody() != null) {
try {
request.getBody().writeTo(bos);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String body = new String(bos.toByteArray());

HttpUriRequest wrappedRequest;
switch (method) {
case "GET":
wrappedRequest = new HttpGet(request.getUrl());
break;
case "POST":
wrappedRequest = new HttpPost(request.getUrl());
wrappedRequest.addHeader("Content-Type", "application/xml");
try {
((HttpPost) wrappedRequest).setEntity(new StringEntity(body));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
case "PUT":
wrappedRequest = new HttpPut(request.getUrl());
wrappedRequest.addHeader("Content-Type", "application/xml");
try {
((HttpPut) wrappedRequest).setEntity(new StringEntity(body));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
case "DELETE":
wrappedRequest = new HttpDelete(request.getUrl());
break;
default:
throw new AssertionError("HTTP operation not supported.");
}

CloseableHttpResponse apacheResponse = null;
try {
apacheResponse = delegate.execute(wrappedRequest);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

if(apacheResponse!=null){
// Perform the HTTP request.
CloseableHttpResponse response = null;
try {
response = delegate.execute(wrappedRequest);

// Return a Retrofit response.
List<Header> retrofitHeaders = toRetrofitHeaders(
response.getAllHeaders());
TypedByteArray responseBody;
if (response.getEntity() != null) {
responseBody = new TypedByteArray("",
toByteArray(response.getEntity()));
} else {
responseBody = new TypedByteArray("",
new byte[0]);
}
System.out.println("this is the response");
System.out.println(new String(responseBody.getBytes()));
return new retrofit.client.Response(request.getUrl(),
response.getStatusLine().getStatusCode(),
response.getStatusLine().getReasonPhrase(), retrofitHeaders,
responseBody);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//failed to return a new retrofit Client
return null;
}

private List<Header> toRetrofitHeaders(org.apache.http.Header[] headers) {
List<Header> retrofitHeaders = new ArrayList<>();
for (org.apache.http.Header header : headers) {
retrofitHeaders.add(new Header(header.getName(), header.getValue()));
}
return retrofitHeaders;
}

private byte[] toByteArray(HttpEntity entity) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
entity.writeTo(bos);
return bos.toByteArray();
}

我的改造配置如下所示:

公共(public)最终 RestAdapter configureService(){

AuthClientRedirector digestAuthMgr = new AuthClientRedirector(username,password,"myhostname","public");

RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint("http://myhostname:8003/endpoint")
.setLogLevel(RestAdapter.LogLevel.FULL)
.setClient(digestAuthMgr);
return builder.build();
}

我很困惑为什么我总是从服务器返回 401。我已经完成了响应构建过程,对我来说它看起来很干净,所以我认为我缺少一些基本的东西。凭据很好,我已经在应用程序外验证了它们。有人走过这条路吗?

最佳答案

您正在使用端口号 443 进行身份验证。

AuthScope authScope = new AuthScope(hostname, 443, scope);

但是,您的真实端口号似乎是8003

RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint("http://myhostname:8003/endpoint")

那么,像下面这样使用端口号8003 进行身份验证 怎么样?

AuthScope authScope = new AuthScope(hostname, 8003, scope);

关于Android - 为 Digest Auth 配置 Retrofit/Apache HttpClient,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31006026/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com