I use adapter based authentication in apps with native iOS to connect my iOS app (swift) to the Mobilefirst server (7.0),
The authentication mechanism works fine, but the problem occurs when the session expires after 10 minutes.
Here you can see the part of the code where I handle authentication and session timeout:
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 {
When the session expires, when the application is in the background, and then returns to the foreground and calls the protected adapter, this part of the code is executed:
timeOutController.performSegueWithIdentifier("logOutDueToTimeOut", sender: nil)
The login is loading with great success, and I can send the credentials for the login again. The problem is that my application can no longer authenticate to the Mobilefirst server by receiving this error:
[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
The request does not seem to have a token or is invalid, but I do not receive the "authrequired" field in the JSON response, so I cannot authenticate again, as it was the first time the application was authenticated before any Mobilefirst session timeout.
Detailed step-by-step execution is the following:
- The application displays the user login screen
- User enters credentials
- When a secure adapter is called during this process, the mobilefirst server returns a response named "authrequired = true". The isCustomResponse method is automatically called and returns true.
- As isCustomResponse returns true, the handleChallenge method is called and, since the login viewController is the visible viewController, the first "If" statement starts authentication.
- Authentication completes successfully, and now the user can navigate throughout the application, accessing all of his protected resources.
- I put the application in the background for 10 minutes (the set timeout of the MobileFirst session on the server).
- I placed the application in the foreground and started navigation again.
- When MobileFirst expires, as soon as I try to call the secure adapter again, the mobilefirst server returns a response with the name "authrequired = true". The isCustomResponse method is automatically called again and returns true.
- As isCustomResponse returns true, the handleChallenge method is called and, since the visible viewController is NOT a loginViewController, the third "If" statement is executed, again displaying the login screen.
- User enters credentials.
- The server returns a 403 response. The isCustomResponse method is automatically called, but returns false, because the response does not contain the "authrequired" field.
Any ideas on how to handle this?