2015-09-18 15 views
5

Ho il seguente codice per autenticare un app iOS a un server MediaWiki:Differenza tra NSURLSession su iOS 8 e iOS 9?

let task = NSURLSession.sharedSession() 
     task.configuration.HTTPAdditionalHeaders = ["Authorization": "Basic " + base64EncodedCredentials] 

     task.dataTaskWithURL(url!) {(data, response, error) in 
      dispatch_async(dispatch_get_main_queue(), { 

       if data != nil { 
        let result = NSString(data: data!, encoding: NSUTF8StringEncoding) 
        if resultIsValid(result) { 
         //Do authentication stuff 
        } else { 
         self.showLoginErrorMessage() 
        } 
       } else { 
        self.showLoginErrorMessage() 
       } 
      }) 
      }.resume() 

Su iOS 8 funziona perfetto e ho ricevuto una risposta OK HTTP 200. Tuttavia, su iOS 9 ricevo un 401 non autorizzato. Sfortunatamente non ho accesso al server per vedere cosa effettivamente riceve, ed è su una rete interna, quindi non posso collegarmi al server. Utilizza l'autenticazione di accesso di base HTTP, quindi presumo che dovrebbe essere lo stesso di qualsiasi altro server con quel tipo di autenticazione.

C'è qualche modifica nell'API da iOS 8 a 9 che potrebbe causare problemi come questo? Ad esempio, potrebbero essere modificate/rimosse/aggiunte altre intestazioni predefinite come il tipo di contenuto o l'agente utente?

Edit: Dopo aver testato con requests.in ho scoperto che l'aggiunta di un Content-Type, questa è una parte dell'intestazione in iOS 8, ma non in iOS 9. In iOS 8 posso ancora ottenere la richiesta attraverso senza impostare il Content-Type, ma è ancora strano che non sia presente nella richiesta di iOS 9.

+0

Questo potrebbe essere un problema [App Transport Security] (https: //developer.apple.com/library/prerelease/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS9.html#//apple_ref/doc/uid/TP40016198-SW14)? –

+0

Sfortunatamente no, allora non otterrei mai il retro non autorizzato 401. Inoltre, ho aggiunto un'eccezione a Info.plist per essere sicuro. – Jorn

+0

È lo stesso per entrambe le versioni. Ho anche un'app per Android che si autentica sul server senza problemi. È SOLO su iOS 9 che ho riscontrato il problema. – Jorn

risposta

3

Sono finalmente riuscito a capirlo! Risulta che in iOS 9 la proprietà HTTPAdditionalHeaders di NSURLSessionConfiguration è di sola lettura e le eventuali modifiche ad esso non si rifletteranno nella NSURLSession corrente. Inoltre, le quattro intestazioni Authorisation, Connection, Host e WWW-Authenticate non possono essere modificate. Pertanto, l'unico modo per eseguire l'autenticazione di accesso di base in iOS 9 è utilizzare NSURLCredential come proposto da quellish.

Per tutti coloro che hanno lo stesso problema, ecco il codice finale ho usato per avere il mio l'autenticazione di lavoro sia per iOS 8 e iOS 9:

let url = NSURL(string: "https://subdomain2.subdomain1.example.com") 

let credential = NSURLCredential(user: username, password: password, persistence: NSURLCredentialPersistence.ForSession) 
let protectionSpace = NSURLProtectionSpace(host: url!.host!, port: 443, `protocol`: url!.scheme, realm: "subdomain2.example.com", authenticationMethod: NSURLAuthenticationMethodHTTPBasic) 
NSURLCredentialStorage.sharedCredentialStorage().setCredential(credential, forProtectionSpace: protectionSpace) 

let task = NSURLSession.sharedSession() 

task.dataTaskWithURL(url!) {(data, response, error) in 
    if data != nil { 
     if responseIsValid(response) { 
      //Do authenticated stuff 
     } else { 
      self.showLoginErrorMessage() 
     }   
    } else { 
     self.showLoginErrorMessage() 
    } 
}.resume() 
+1

In futuro, si potrebbe dare un'occhiata a uno strumento come http://www.charlesproxy.com per aiutare a decifrare il traffico web bidirezionale. È bello b/c puoi vedere entrambi i lati della conversazione, ed è molto più facile da configurare per lo sniffing wireless di https://www.wireshark.org/ – fullofsquirrels