需要帮助为Android创建摘要式身份验证

Gee*_*Out 3 android digest-authentication android-asynctask

到目前为止我有这个代码:

private class DownloadWebPageTask extends AsyncTask<String, Void, String> 
{
        @Override
        protected String doInBackground(String... theParams) 
        {
            String myUrl = theParams[0];
            String myEmail = theParams[1];
            String myPassword = theParams[2];

            HttpPost post = new HttpPost(myUrl);
            post.addHeader("Authorization","Basic "+ Base64.encodeToString((myEmail+":"+myPassword).getBytes(), 0 ));
            ResponseHandler<String> responseHandler = new BasicResponseHandler();

            String response = null;

            try 
            {
                    response = client.execute(post, responseHandler);
                InputStream content = execute.getEntity().getContent();

                BufferedReader buffer = new BufferedReader(
                            new InputStreamReader(content));
                    String s = "";
                    while ((s = buffer.readLine()) != null) 
                    {
                        response += s;
                    }
                } 
                catch (Exception e) 
                {
                    e.printStackTrace();
                }

            return response;
        }


        @Override
        protected void onPostExecute(String result) 
        {
            }

}
Run Code Online (Sandbox Code Playgroud)

这段代码无法编译,因为我遇到了以下问题:

                response = client.execute(post, responseHandler);
                InputStream content = execute.getEntity().getContent();
Run Code Online (Sandbox Code Playgroud)

我通过修改各种示例来获取该代码,并且不确定客户端应该是什么对象,以及第一行是否只是让我获得服务器响应,或者我必须采用获取InputStream和读取服务器的路径回应?

请帮我理解如何正确地做到这一点.

谢谢!

小智 5

我已设法使用OkHttp进行摘要式身份验证.在这个代码示例中,我还使用了Dagger和Robospice-retrofit.我所做的是创建一个OkHttp Authenticator并将其分配给我的自定义OkHttp客户端.

authenticator类实现一个authenticate方法,只要服务器遇到401错误就会调用该方法,并期望返回一个Authorization标头(如果它需要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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,身份验证器将在使用提供程序构建的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,客户端在createRestAdapterBuilder函数中设置为RetrofitRobospice服务器:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)