android-截击错误未找到身份验证挑战

android-截击错误未找到身份验证挑战,android,authentication,android-volley,Android,Authentication,Android Volley,我试图使用一些遗留代码,但在使用截击时遇到了一个问题 我试图得到一个api,我们的主要网站已经和它的工作良好的一个帐户,但不是另一个。我试图找出请求URL/头中可能存在的差异,以及响应中返回的内容,但我似乎无法在截取代码中找到将其打印到日志的方法 我得到的错误是 com.android.volley.NoConnectionError: java.io.IOException: No authentication challenges found 我读过很多书,说这可能是401计划的结果,但我

我试图使用一些遗留代码,但在使用截击时遇到了一个问题

我试图得到一个api,我们的主要网站已经和它的工作良好的一个帐户,但不是另一个。我试图找出请求URL/头中可能存在的差异,以及响应中返回的内容,但我似乎无法在截取代码中找到将其打印到日志的方法

我得到的错误是

com.android.volley.NoConnectionError: java.io.IOException: No authentication challenges found
我读过很多书,说这可能是401计划的结果,但我真的不知道这意味着什么,或者至少不知道如何证明/测试这一点。我真的很困惑,它只适用于一个账户,而不适用于另一个账户

url略有不同,一个是我们的英国网站,另一个是我们的AM,但除此之外没有区别


感谢

发生此错误的原因是服务器发送401(未经授权),但没有给出“WWW-Authenticate”,这是客户端下一步操作的提示。“WWW-Authenticate”头告诉客户端需要哪种身份验证(或)。这在无头http客户机中通常不是很有用,但标准就是这样定义的。发生此错误的原因是lib试图解析“WWW Authenticate”头,但无法解析

如果可以更改服务器,可能的解决方案:

  • 添加一个假的“WWW-Authenticate”标题,如:
    WWW-Authenticate:Basic realm=“fake”
    。这只是一个解决方案,不是一个解决方案,但它应该可以工作,并且http客户机感到满意
  • 使用HTTP状态代码
    403
    而不是
    401
    。它的语义是不同的,通常在使用登录401时是正确的响应(),但它已经足够接近了
如果无法更改服务器,可能的解决方案:

正如@ErikZ在他的文章中所写的,你可以尝试一下

HttpURLConnection connection = ...;
try {
    // Will throw IOException if server responds with 401.
    connection.getResponseCode(); 
} catch (IOException e) {
    // Will return 401, because now connection has the correct internal state.
    int responsecode = connection.getResponseCode(); 
}

我也在这里发布了这个消息:

事实上,我已经通过在服务器响应中包含
WWW-Authenticate
头解决了这个问题

但是,如果您添加标题
WWW Authenticate:Basic realm=“
,并且您的API也被web客户端使用,某些web浏览器将触发一个弹出窗口,询问基本凭据

对我来说,正确的解决方案是使用自定义方案。如本文所述,我在报头响应中使用
xBasic
而不是
Basic

WWW-Authenticate:xBasic-realm=”“


使用此标头,Volley不仅可以正确解析响应,而且可以避免web浏览器显示身份验证弹出窗口。

在初始化Volley RequestQueue时,我能够捕获此客户端:

Volley.newRequestQueue(getApplicationContext(), new HurlStack() {
        @Override
        public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders) {
            try {
                return super.performRequest(request, additionalHeaders);
            } catch (AuthFailureError authFailureError) {
                authFailureError.printStackTrace();
                // Log out / whatever you need to do here
            } catch (IOException e) {
                e.printStackTrace();
                if (e.getMessage().equals("No authentication challenges found")) {
                    // This is the error.  You probably will want to handle any IOException, not just those with the same message.
                }
            }
            return null;
        }
});
Volley.newRequestQueue(getApplicationContext(),new HurlStack()){
@凌驾
公共HttpResponse performRequest(请求、映射附加头){
试一试{
返回super.performRequest(请求、附加标题);
}捕获(AuthFailureError AuthFailureError){
authFailureError.printStackTrace();
//注销/您需要在此处执行的任何操作
}捕获(IOE异常){
e、 printStackTrace();
if(e.getMessage().equals(“未找到身份验证问题”)){
//这就是错误所在。您可能希望处理任何IOException,而不仅仅是那些具有相同消息的IOException。
}
}
返回null;
}
});

如果服务器崩溃,您可能会遇到此问题。 步骤:

  • 停止tomcat服务器

  • 转到运行->服务->重新启动数据库(例如:postgres)

  • 启动tomcat服务器


  • 您可以检查e是否为AuthFailureError实例

    Log.e(TAG, "AuthFailureError: " + (e instanceof AuthFailureError));
    

    这是一个错误,表明在执行截击请求时无法建立连接。@Raghunandan您知道是否还有其他方法可以获取更多信息吗?任何响应细节等?无法建立连接。如果没有联系,你有机会去哪里response@bbalazs我不认为这有什么帮助,我已经读过了。“我认为这与截击无关。”“拉古南丹,是什么让你认为无法建立任何联系?我以为是在身份验证不匹配的时候,我正试图发送一个带有摘要身份验证的头,但不知道该怎么做(仍在搜索答案)。你有没有关于如何在Android Volley中进行摘要(甚至是基本的)身份验证的示例?basic和Digest只是放了一个标题,在basic中看起来像“Authorization:basic QWxHzGrpBjPvcGvuUiHnlc2FTZQ==”,在Digest中更复杂-这对Volley不是特别的,你只放了一个标题(google在Volley中介绍了如何做到这一点)很抱歉,我很久以前问过这个问题,我甚至不记得它与什么有关,加上遗留项目已经关闭。我会对你的答案投赞成票,因为你付出了努力,但我无法检查它是否正确,所以我恐怕不会选择它作为答案。这很公平。我会留下它,因为我花了相当长的时间来理解这个问题-学习REST/HTTP规范有时并不像你想的那样直接:)如何在服务器响应中添加WWW认证头对不起,我很久以前问过这个问题,我甚至不记得它与什么有关,加上遗留项目已经关闭。我会对你的答案投赞成票,因为你付出了努力,但我无法检查它是否正确,所以我恐怕不会选择它作为答案。@Russ没问题!只是想帮助其他人寻找答案:)这只是一张便条。您可以为方案使用任何字符串(如上文所述的
    xBasic
    ),但还必须包括
    realm=“”
    (包括引号)以避免引发异常。如何在服务器响应中添加WWW Authenticate标头