2016-05-13 3 views
5

Ich verwende Adapter-based authentication in native iOS applications, um meine native ios-Anwendung (swift) mit dem Mobilefirst-Server (7.0) zu verbinden.Der Mobilefirst-Server gibt den Fehler 403 nach der Sitzungszeitlimitbehandlung in einer nativen ios-Anwendung zurück.

Der Mechanismus der Authentifizierung funktioniert gut, aber das Problem tritt auf, wenn die Sitzung nach 10 Minuten abläuft.

Hier können Sie den Teil des Codes sehen, wo ich die Authentifizierung und die Session-Timeout Griff:

override func isCustomResponse(response: WLResponse!) -> Bool { 
    if response != nil && response.responseJSON != nil { 
     let responseJson: NSDictionary = response.responseJSON as NSDictionary 
     if responseJson.objectForKey("authRequired") != nil{ 
      return responseJson.objectForKey("authRequired") as! Bool 
     } 
    } 
    return false 
} 

override func handleChallenge(response: WLResponse!) { 

    NSLog("A login form should appear") 

    if self.vc.navigationController?.visibleViewController!.isKindOfClass(LoginViewController) == true { 
     NSLog("Already the login form") 
     dispatch_async(dispatch_get_main_queue()) { 
      let loginController : LoginViewController! = self.vc.navigationController?.visibleViewController as? LoginViewController 

      let myInvocationData = WLProcedureInvocationData(adapterName: "AuthenticationJavaAdapter", procedureName: "authenticate") 
      myInvocationData.parameters = [loginController.userID, loginController.userPass] 
      self.submitAdapterAuthentication(myInvocationData, options: nil) 
     } 
    } else if (self.vc.navigationController?.visibleViewController!.isKindOfClass(SignUpViewController) == true) { 
     NSLog("Already the signup form") 
     dispatch_async(dispatch_get_main_queue()) { 
      NSLog("AuthenticationJavaAdapter") 
      let sigupController : SignUpViewController! = self.vc.navigationController?.visibleViewController as? SignUpViewController 

      let myInvocationData = WLProcedureInvocationData(adapterName: "AuthenticationJavaAdapter", procedureName: "authenticate") 
      myInvocationData.parameters = [sigupController.userID, sigupController.userPass] 
      self.submitAdapterAuthentication(myInvocationData, options: nil) 
     } 
    }else { //TEST 
     NSLog("A login form is not there yet") 
     //After 10 minutes this will execute, it will perform a unwind segue to the login 
     //timeOutController is a global var declared in LoginViewController 
     timeOutController.performSegueWithIdentifier("logOutDueToTimeOut", sender: nil) 
    } 
} 

Wenn die Sitzung im Hintergrund ist die Anwendung abläuft und dann in den Vordergrund kommt zurück und ruft einen geschützten Adapter dieser Teil des Code ausgeführt wird.

timeOutController.performSegueWithIdentifier("logOutDueToTimeOut", sender: nil) 

die Login-Ansicht Lasten mit Erfolg und ich kann wieder die Anmeldeinformationen einreichen einzuloggen in dem Problem ist, dass meine Anwendung nicht mehr in der Lage ist, an den Mobilefirst-Server zu authentifizieren, bekommen th Fehler:

[DEBUG] [WL_REQUEST] -[WLRequest requestFinished:] in WLRequest.m:385 :: no token present 
2016-05-13 12:58:29.241 BNNDesignCollection[46327:318014] [DEBUG] [WL_PUSH] -[WLPush updateToken:] in WLPush.m:410 :: Server token is (null) 
.... 
.... 
.... 
2016-05-13 12:58:29.352 BNNDesignCollection[46327:318014] [DEBUG] [WL_AFHTTPCLIENTWRAPPER_PACKAGE] -[WLAFHTTPClientWrapper requestFailed:error:] in WLAFHTTPClientWrapper.m:335 :: Response Status Code : 403 
2016-05-13 12:58:29.352 BNNDesignCollection[46327:318014] [DEBUG] [WL_AFHTTPCLIENTWRAPPER_PACKAGE] -[WLAFHTTPClientWrapper requestFailed:error:] in WLAFHTTPClientWrapper.m:336 :: Response Error : Expected status code in (200-299), got 403 

Es scheint, dass die Anforderung nicht ein Token hat oder ungültig ist, aber ich habe nicht den „authrequired“ -Feld in der JSON-Antwort erhalten, so dass ich nicht noch einmal authentifizieren kann, wie ich tat Beim ersten Mal authentifiziert sich die Anwendung vor einem Timeout der Mobilefirst-Sitzung.

Der detaillierte Schritt für Schritt Ausführung ist dieses:

  1. Die Anwendung zeigt den Anmeldebildschirm für den Benutzer
  2. Der Benutzer gibt die Anmeldeinformationen
  3. als geschützte Adapter während dieses Prozesses aufgerufen wird, die Der mobilefirst Server gibt eine Antwort mit "authrequired = true" zurück. Die isCustomResponse-Methode wird automatisch aufgerufen und gibt "true" zurück.
  4. Wenn isCustomResponse den Wert true zurückgibt, wird die Methode handleChallenge aufgerufen, und da der visible ViewController der loginViewController ist, wird die erste "If" -Anweisung ausgeführt, die die Authentifizierung startet.
  5. Die Authentifizierung ist erfolgreich und der Benutzer kann jetzt durch die Anwendung navigieren, indem er auf alle geschützten Ressourcen zugreift.
  6. Ich legte die Anwendung im Hintergrund für 10 Minuten (Etablierte MobileFirst Session Timeout auf dem Server).
  7. Ich legte die Anwendung in den Vordergrund und starten die Navigation erneut.
  8. Nachdem die MobileFirst-Sitzung abgelaufen ist, gibt der mobilefirst-Server nach dem Versuch, einen geschützten Adapter erneut anzurufen, eine Antwort mit "authrequired = true" zurück. Die isCustomResponse-Methode wird automatisch erneut aufgerufen und gibt "true" zurück.
  9. Wenn isCustomResponse true zurückgibt, wird die Methode handleChallenge aufgerufen, und da der visible viewController NICHT der loginViewController ist, wird die dritte "If" -Anweisung ausgeführt, die den Anmeldebildschirm erneut anzeigt.
  10. Der Benutzer gibt die Anmeldeinformationen ein.
  11. Der Server gibt eine 403-Antwort zurück. Die isCustomResponse-Methode wird automatisch aufgerufen, gibt aber false zurück, da die Antwort das Feld "authrequired" nicht enthält.

Irgendwelche Ideen, wie man damit umgeht?

+0

Woher wissen Sie (im Code), dass die Sitzung abgelaufen ist? Sie haben geschrieben, dass Sie nach Ablauf der Sitzung einen Übergang durchführen, aber ich sehe nirgends in Ihrem Code den Teil, der eine Zeitüberschreitung feststellt. –

+0

Die isCustomResponse-Methode des Challenge-Handlers wird jedes Mal aufgerufen, wenn eine Antwort vom Server empfangen wird. Wenn isCustomResponse den Wert true zurückgibt, ruft das Framework die Methode handleChallenge auf. Dies geschieht, wenn in der Antwort ein Feld "authRequired" erkannt wird. Wenn die Sitzung abläuft und ein geschützter Adapter aufgerufen wird, gibt isCustomResponse true zurück und die Methode handleChallenge wird ausgeführt. Diese Erkennung funktioniert einwandfrei und der Anmeldebildschirm wird erneut geladen.Bei einer erneuten Anmeldung gibt der worklight-Server das Feld "auth required" nicht erneut zurück, um die Authentifizierung erneut auszuführen. –

+0

Sorry, verstehe ich immer noch nicht. "Aber, wenn du dich wieder anmeldest" - was meinst du mit login nochmal? Wenn 'isCustomResponse' wahr zurückgegeben wird, bedeutet dies, dass Sie 'auth required' wie erwartet erhalten haben. Bitte aktualisieren Sie Ihre Frage Schritt für Schritt mit sehr detailliert, einschließlich Code-Schnipsel. –

Antwort

2

Es gibt mehrere Probleme, die ich mit Ihrem Authentifizierungsablauf sehen kann.

  • Ihre Schritte beginnen mit "Die Anwendung zeigt den Anmeldebildschirm für den Benutzer". Fixieren Sie die Anwendung mit einem Anmeldebildschirm? Adapterbasierte Authentifizierung unterstützt keine "präventive" Authentifizierung. Bedeutet nur eine Herausforderung sollte den Anmeldebildschirm zeigen. Die übliche Vorgehensweise besteht darin, eine geschützte Ressource während des App-Starts aufzurufen oder die API login zum Auslösen der Abfrage zu verwenden. Ihr sollte dann den Anmeldebildschirm anzeigen.
  • "Während dieses Prozesses wird ein geschützter Adapter aufgerufen". Sie rufen eine geschützte Ressource in der Mitte des Authentifizierungsablaufs auf. Nicht gut. Tu das nicht.
  • Ihre handleChallenge sendet automatisch die Anmeldeinformationen, wenn der View Controller LoginViewController bereits auf dem Bildschirm angezeigt wird. Was passiert, wenn der Benutzer falsche Anmeldedaten eingibt? Würde es nicht die schlechten Anmeldeinformationen in einer Schleife senden? Normalerweise, wenn LoginViewController bereits auf dem Bildschirm angezeigt wird, möchten Sie nur die Benutzeroberfläche aktualisieren, zum Beispiel "falsche Anmeldeinformationen, versuchen Sie es erneut".
  • Klicken Sie auf die Schaltfläche "Login" sollte sein, was submitAdapterAuthentication auslöst. Eine Challenge sollte nicht submitAdapterAuthentication auslösen.
  • Jede eingehende Anfrage muss beantwortet werden, bevor Sie etwas anderes tun. Das heißt, sobald aufgerufen wird, können Sie nicht versuchen, weitere geschützte Anfragen zu stellen oder eine andere Anfrage auszulösen.

In Bezug auf Ihre besonderen Problem, das ist, was ich glaube, nach dem Timeout passiert:

  • handleChallenge genannt wird, die den Login-Bildschirm öffnet sich.
  • Sie haben geschrieben, dass "während dieses Prozesses ein geschützter Adapter aufgerufen wird", den Sie nicht ausführen können, da Sie sich mitten in einer Herausforderung befinden.
  • Die Anwendung tritt in einen instabilen Zustand ein.

Wenn Sie den Kommentaren folgen, die ich oben geschrieben habe, sollten Sie in Ordnung sein. Aber es erfordert einige architektonische Änderungen an Ihrer Anwendung. Die Reihenfolge, in der Ereignisse auftreten, ist wichtig:

  1. Stellen Sie eine geschützte Anfrage.
  2. handleChallenge zeigt das Login-Formular.
  3. Benutzer klickt auf Senden.
  4. submitAdapterAuthentication

Es ist egal, ob es der erste Lauf, vorbeugende oder nach der Zeit aus ist, stellen Sie sicher, dass Sie die Reihenfolge der Operationen folgen.

+0

Vielen Dank für die Lösung! Es ist wirklich vollständig, aber während ich darüber nachdenke, wie ich es implementieren kann, muss ich hinzufügen, dass sich unsere Anwendung vor dem Zugriff auf den MobileFirst-Server gegen eine Firewall authentifizieren muss. Daher wird der Challenge-Handler nicht vor der Authentifizierung durch diese Firewall als MobileFirst-Server ausgelöst nur zugänglich, wenn die Anwendung gegen die Firewall authentifiziert wurde. Deshalb laden wir vorher den Login-Bildschirm. Sie wissen, wie wir damit umgehen könnten? –

+0

Wie funktioniert die Authentifizierung mit Ihrer Firewall? Welche Art von Authentifizierung? –

+0

Es verwendet Basic Access Authentication, also senden wir den Benutzernamen und das Passwort in einer Kopfzeile –

Verwandte Themen