无法使用bare-bones-digest库在Android中实现Digest Auth

Posted

技术标签:

【中文标题】无法使用bare-bones-digest库在Android中实现Digest Auth【英文标题】:Unable To Implement Digest Auth In Android Using bare-bones-digest library 【发布时间】:2018-01-29 06:18:21 【问题描述】:

我正在尝试在 android 中实现 Digest auth。我读了很多帖子,他们说 HttpUrlConnection 类不支持 Digest 身份验证。但是,我已经使用 bare-bones-digest 库实现了它。现在它工作正常,但 API 调用变得非常慢。与使用基本身份验证相比,加载数据需要双倍的时间。他们说使用 base-bones-digest 可以避免每个请求发送两次,在随后的请求中,客户端可以重用挑战。只有第一个请求必须发送两次。但是没有给出实现。

HttpURLConnection httpURLConnection = null;
        try 
            if(mAuthorizationString != null && !mAuthorizationString.equals(""))
                URL url = new URL(apiEndpoint);
                httpURLConnection = (HttpURLConnection) url.openConnection();
                DigestAuthentication auth = DigestAuthentication.fromResponse(httpURLConnection);
                // ...with correct credentials
                auth.username("username").password("password");
                httpURLConnection.setRequestProperty(DigestChallengeResponse.HTTP_HEADER_AUTHORIZATION,
                        mAuthorizationString);
            
            else
                URL url = new URL(apiEndpoint);
                httpURLConnection = (HttpURLConnection) url.openConnection();

                // Step 2. Make the request and check to see if the response contains an authorization challenge
                if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED) 
                    // Step 3. Create an authentication object from the challenge...
                    DigestAuthentication auth = DigestAuthentication.fromResponse(httpURLConnection);
                    // ...with correct credentials
                    auth.username("username").password("password");

                    // Step 4 (Optional). Check if the challenge was a digest challenge of a supported type
                    if (!auth.canRespond()) 
                        // No digest challenge or a challenge of an unsupported type - do something else or fail
                        return httpURLConnection;
                    

                    // Step 5. Create a new connection, identical to the original one...
                    httpURLConnection = (HttpURLConnection) url.openConnection();

                    mAuthorizationString = auth.getAuthorizationForRequest(requestMethod, httpURLConnection.getURL().getPath());

                    // ...and set the Authorization header on the request, with the challenge response
                    httpURLConnection.addRequestProperty(DigestChallengeResponse.HTTP_HEADER_AUTHORIZATION,
                            mAuthorizationString);
                
            

         catch (IOException e) 
            e.printStackTrace();
        

【问题讨论】:

【参考方案1】:

我已通过如下更新代码自行修复。

HttpURLConnection httpURLConnection = null;
        try 
            URL url = new URL(apiEndpoint);
            httpURLConnection = (HttpURLConnection) url.openConnection();
            if(sAuthorizationString != null && !sAuthorizationString.equals(""))
                httpURLConnection.addRequestProperty(DigestChallengeResponse.HTTP_HEADER_AUTHORIZATION,
                        sAuthorizationString);
            
            else

                // Step 2. Make the request and check to see if the response contains an authorization challenge
                if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED) 
                    // Step 3. Create an authentication object from the challenge...
                    DigestAuthentication auth = DigestAuthentication.fromResponse(httpURLConnection);
                    // ...with correct credentials
                    auth.username("username").password("password");

                    // Step 4 (Optional). Check if the challenge was a digest challenge of a supported type
                    if (!auth.canRespond()) 
                        // No digest challenge or a challenge of an unsupported type - do something else or fail
                        return httpURLConnection;
                    

                    // Step 5. Create a new connection, identical to the original one...
                    httpURLConnection = (HttpURLConnection) url.openConnection();

                    sAuthorizationString = auth.getAuthorizationForRequest(requestMethod, httpURLConnection.getURL().getPath());

                    // ...and set the Authorization header on the request, with the challenge response
                    httpURLConnection.addRequestProperty(DigestChallengeResponse.HTTP_HEADER_AUTHORIZATION,
                            sAuthorizationString);
                
            

         catch (IOException e) 
            e.printStackTrace();
        

【讨论】:

以上是关于无法使用bare-bones-digest库在Android中实现Digest Auth的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 clojure 模式库在映射中使用字符串键验证值

Create an Android library

Spring Boot存储库在测试期间无法正常工作

第三个库在编译期间报告错误(使用 cocoaPods)

如何使用 C# 中的 Emgu CV 库在图像上绘制矩形。举个例子

使用govmomi库在golang中的零点差异