2013-12-16 12 views
11

Sto provando a lavorare con qualche codice legacy e mi sono imbattuto in un problema quando usavo il volley.android - errore volley Nessun problema di autenticazione trovato

Sto provando ad arrivare a un'api che il nostro sito principale ha e funziona bene per un account, ma non un altro. Sto cercando di capire quali potrebbero essere le differenze nella richiesta URL/intestazioni e anche cosa sta tornando nella risposta, ma non riesco a trovare un modo nel codice volley per stampare questo nel log.

L'errore che sto ottenendo è

com.android.volley.NoConnectionError: java.io.IOException: No authentication challenges found 

ho letto in giro che questo potrebbe essere dovuto ad una risposta 401, ma io non so davvero che cosa significa o almeno come per dimostrare/prova questo Sono davvero confuso che funzioni per un account e non per un altro.

L'URL è leggermente diverso come uno è per il nostro sito nel Regno Unito e l'altro il nostro AM, ma a parte questo non c'è alcuna differenza.

Grazie

+0

è un errore che indica che non è possibile stabilire alcuna connessione durante l'esecuzione di una richiesta Volley. – Raghunandan

+0

@Raghunandan sai se c'è comunque qualche informazione in più? Eventuali dettagli di risposta, ecc.? –

+0

non è possibile stabilire alcuna connessione. se non ci sono connessioni dove è possibile ottenere la risposta – Raghunandan

risposta

8

Questo errore si verifica perché il server invia una 401 (non autorizzato), ma non dà una "WWW-Authenticate", che è un suggerimento per il cliente che cosa fare dopo. L'intestazione "WWW-Authenticate" indica al client quale tipo di autenticazione è necessario (Basic o Digest). Questo di solito non è molto utile nei client http headless, ma è così che viene definito lo standard. L'errore si verifica perché la lib prova ad analizzare l'intestazione "WWW-Authenticate" ma non può.

Possibili soluzioni Se è possibile modificare il server:

  • Aggiungi un falso "WWW-Authenticate" intestazione come: WWW-Authenticate: Basic realm="fake". Questa è una semplice soluzione alternativa, non una soluzione, ma dovrebbe funzionare e il client http è soddisfatto.
  • Utilizzare il codice di stato HTTP 403 anziché 401. È semantico non è la stessa cosa e di solito quando si lavora con login 401 è una risposta corretta (see here for a detailed discussion) ma è abbastanza vicina.

Possibili soluzioni se non è possibile modificare il server:

Come @ErikZ ha scritto nel suo post si potrebbe usare una prova & cattura

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

ho anche postato questo qui: java.io.IOException : No authentication challenges found

+0

Sto provando a inviare un'intestazione con Autenticazione del digest, ma non riesco a capire come farlo (sto ancora cercando una risposta). Avete qualche esempio su come eseguire un'autenticazione Digest (o anche di base) su Android-Volley? –

+0

Basic e Digest è solo mettere un colpo di testa che assomiglia a questo "Autorizzazione: QWxhZGRpbjpvcGVuIHNlc2FtZQ base ==" in base e più complicato in digest - questo non è speciale al volo, basta mettere le intestazioni set (Google su come farlo nel volley) – for3st

+0

Mi dispiace di aver fatto questa domanda tanto tempo fa, non ricordo nemmeno a cosa si riferisce, inoltre quel progetto legacy è stato chiuso. Eviterò la tua risposta per lo sforzo che hai inserito, ma non ho modo di controllare che sia giusto, quindi non lo selezionerò come risposta temo. –

8

In effetti, ho risolto questo problema includendo l'intestazione WWW-Authenticate nella risposta del server.

Tuttavia, se si aggiunge l'intestazione WWW-Authenticate: Basic realm="" e l'API viene utilizzata anche dai client Web, alcuni browser Web attivano un pop-up che richiede le credenziali di base.

Per me la soluzione giusta è stata l'utilizzo di uno schema personalizzato. Come spiegato in questo blog post, utilizzo xBasic anziché Basic nella risposta dell'intestazione.

WWW-Authenticate: xBasic realm=""

Con questa intestazione, non solo Volley analizza la risposta corretta, ma anche evitare i browser web che mostrano l'autenticazione pop-up.

+0

Mi dispiace ho fatto questa domanda così tanto tempo fa, non ricordo nemmeno a che cosa si riferisca, in più quel progetto legacy è stato chiuso. Eviterò la tua risposta per lo sforzo che hai inserito, ma non ho modo di controllare che sia giusto, quindi non lo selezionerò come risposta temo. –

+0

@Russ Nessun problema! Volevo solo aiutare altre persone in cerca di una risposta :) –

+0

Solo una nota per accompagnare questo. Puoi usare qualsiasi stringa per lo schema (ad es. 'XBasic' come sopra), ma anche il' realm = "" '(comprese le virgolette) deve essere incluso per evitare che l'eccezione venga lanciata. –

0

sono stato in grado di catturare questo lato client durante l'inizializzazione del RequestQueue volley:

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

Se Server si è schiantato, si può affrontare questo problema. Passi:

  1. arrestare il server Tomcat

  2. goto Run -> Servizi -> riavviare il database (es: Postgres)

  3. Avviare il server Tomcat.

0

È possibile controllare e is instanceof AuthFailureError.

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