android - volley error No authentication challenges found

后端 未结 5 1884
遇见更好的自我
遇见更好的自我 2020-12-16 17:41

I am trying to work with some legacy code and have come up against an issue when using volley.

I am trying to get to an api that our main site has and it works fine

相关标签:
5条回答
  • 2020-12-16 18:08

    You can check e is instanceof AuthFailureError.

    Log.e(TAG, "AuthFailureError: " + (e instanceof AuthFailureError));
    
    0 讨论(0)
  • 2020-12-16 18:14

    Indeed, I have solved this problem by including the WWW-Authenticate header in the server response.

    However, if you add the header WWW-Authenticate: Basic realm="" and your API is also consumed by web clients, some web browsers will trigger a pop up asking for basic credentials.

    For me the right solution has been using a custom scheme. As explained in this blog post, I use xBasic instead of Basic in the header response.

    WWW-Authenticate: xBasic realm=""

    With this header, not only Volley parses the response correctly, but I also avoid web browsers showing the authentication pop up.

    0 讨论(0)
  • 2020-12-16 18:14

    This error happens because the server sends a 401 (Unauthorized) but does not give a "WWW-Authenticate" which is a hint for the client what to do next. The "WWW-Authenticate" Header tells the client which kind of authentication is needed (either Basic or Digest). This is usually not very useful in headless http clients, but that's how the standard is defined. The error occurs because the lib tries to parse the "WWW-Authenticate" header but can't.

    Possible solutions if you can change the server:

    • Add a fake "WWW-Authenticate" header like: WWW-Authenticate: Basic realm="fake". This is a mere workaround not a solution, but it should work and the http client is satisfied.
    • Use HTTP status code 403 instead of 401. It's semantic is not the same and usually when working with login 401 is a correct response (see here for a detailed discussion) but its close enough.

    Possible solutions if you can't change the server:

    As @ErikZ wrote in his post you could use a try&catch

    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(); 
    }
    

    I also posted this here: java.io.IOException : No authentication challenges found

    0 讨论(0)
  • 2020-12-16 18:15

    I was able to catch this client-side when initializing the 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;
            }
    });
    
    0 讨论(0)
  • 2020-12-16 18:32

    If Server crashed, you may face this problem. Steps:

    1. Stop the tomcat server

    2. goto Run -> Services -> restart your database (ex: postgres)

    3. Start the tomcat server.

    0 讨论(0)
提交回复
热议问题