Domanda

Ho un app che comunica con un server che utilizza l'autenticazione HTTP Digest.

Mi sembra che la gestione 'session' all'interno del iPhone è piuttosto "scatola nera" per noi sviluppatori. E 'vero che non possiamo vedere come gestisce il quadro / persiste sessioni HTTP?

Se sto solo essere fioca qui, qualcuno dovrebbe preoccuparsi di spiegare come gestire probabilmente l'autenticazione HTTP Digest su iPhone?

La mia corsa è di base attraverso:

  • Fare una richiesta a un URL protetto
  • Server invia un 401
  • client crea e persiste una credenziale, e lo passa al server
  • server verifica delle credenziali, completa la richiesta se verificato, invia un altro 401 in caso contrario.
  • fare una richiesta successiva per garantire url
  • richieste al server di autorizzazione di nuovo ........

Questo funziona per le singole richieste, ma se faccio supplementari, le richieste successive, il server richiede nuovamente l'autorizzazione. Il server ha persistito una sessione per l'utente particolare, ma l'iPhone non è fare una richiesta all'interno della stessa sessione per qualche motivo ... Di conseguenza, il server deve buttare fuori l'oggetto di autenticazione e crearne uno nuovo ogni volta che il client fa una richiesta a un URL protetto.

Sono sicuro che questo non è un comportamento corretto.

Se guardiamo a come un browser si comporta in questa situazione:

  • Browser richiede dati da URL sicura
  • server invia 401
  • browser richiede all'utente di credenziali, persiste, la trasmette al server
  • server verifica delle credenziali, la restituzione di dati se verificato, invia un altro 401 in caso contrario.
  • le successive richieste fatte per garantire URL non sono richieste le credenziali perché il browser gestisce la sessione.

Sto creando la NSURLCredential e persistente all'interno del NSURLCrendtialStorage. Poi, quando l'applicazione riceve il 'didReceiveAuthenticationChallenge' a recuperare le credenziali dal deposito e passare di nuovo, creando le credenziali se non esiste (alla prima richiesta).

Qualsiasi aiuto sarebbe molto apprezzato. Grazie.

È stato utile?

Soluzione

Per prima cosa, è quello di dimenticare le sessioni HTTP, in quanto questi non interagiscono con autenticazione Digest log-in attivi (v'è una sorta di capacità di informazioni di sessione, ma è diverso).

In effetti, uno dei motivi principali per l'utilizzo di Digest, è quello di non dover usare le sessioni solo per mantenere uno stato connesso in. Le sessioni sono pesanti e male scalabilità.

Non ho potuto dire con certezza che cosa il vostro problema è, ma so cosa avrei verifico prima, che è corretto uso della creazione stantio e corretta nonce.

User-agent in grado di gestire solo l'autenticazione, senza riottenere l'utente se viene chiesto loro di gestire lo stesso nonce, o in un altro caso verrò a tardi (più facile da spiegare in questo ordine).

Se avete lo stesso nonce utilizzato in ogni richiesta, allora l'user-agent continuerà ad usarlo insieme al "HA1" dal user / pass per richiedere le risorse successive. Questo viene fatto preventivamente, quindi la sfida non accade mai.

Naturalmente, utilizzando la stessa nonce introduce un elemento di insicurezza, come gli attacchi di riproduzione diventano banali a chiunque in grado di fiutare il traffico. Nonces dovranno cambiare su base regolare.

Quindi, se si riceve una richiesta da un user-agent con un'intestazione di autorizzazione valida, ma la ragione è valida è che il nonce è sbagliato (è utilizzarne uno scaduto) poi nella vostra sfida includere "stantio = true" (default è false). Questo informa l'utente-agente che il motivo per respingere la nonce è obsoleto (ovviamente le altre informazioni possono anche essere sbagliato, ma questo non importa come non si ha intenzione di lasciarlo giocare in entrambi i casi).

Dopo aver ricevuto un tale stantio = true l'user-agent saprà che non è autorizzato, ma invece di riottenere l'utente (o un'eccezione se si tratta di un componente UI-less) saranno riprovare i vecchi criteri con il nuovo nonce.

Non riesco a capire se tutto questo è ciò che è ti interessano, ma il modo in cui nonce e stantio sono determinati e segnalati è certamente la prima cosa che guardo.

Altri suggerimenti

Ho scritto un applicazione per iPhone con l'autenticazione HTTP e sperimentato ciò che si descrive. (La mia applicazione utilizza l'autenticazione di base invece che l'autenticazione del digest, ma che non fa una grande differenza qui.)

La causa del problema è sul lato iPhone. Il server è necessario per rispondere con 401 se l'iPhone non invia le credenziali nell'intestazione richiesta HTTP. E infatti non lo fa, anche se facilmente potrebbe una volta che la credenziale è memorizzata nella memoria credenziali.

Questo strano comportamento ha avuto un grave effetto sulla velocità dell'applicazione in quanto ogni richiesta ha causato due di andata e ritorno al server invece di uno (il primo con lo stato 401, il secondo con 200).

Ho risolto impostando manualmente le credenziali nell'intestazione della richiesta HTTP:

NSString* credentials = [NSString stringWithFormat: @"%@:%@", usr, pwd];
const char* credentialsChars = [credentials cStringUsingEncoding: NSUTF8StringEncoding];
credentials = [CommunicationUtil stringBase64WithData: (const UInt8*) credentialsChars length: strlen(credentialsChars)];
NSString* authorizationHeader = [NSString stringWithFormat: @"Basic %@", credentials];

NSMutableURLRequest* request =
    [[NSMutableURLRequest alloc] initWithURL: url 
        cachePolicy: NSURLRequestReloadIgnoringLocalCacheData
        timeoutInterval: 15];

    [request setValue: authorizationHeader forHTTPHeaderField: @"Authorization"];

Ora la mia applicazione funziona molto bene e è molto reattivo.

La soluzione avrà un aspetto leggermente diverso per l'autenticazione digest. Ma si otterrà l'idea.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top