I'm using Adapter-based authentication in native iOS applications to connect my native ios application (swift) to the Mobilefirst server (7.0).
The mechanism of authentication is working fine but the problem comes when the session expires after 10 minutes.
Here you can see the part of the code where I handle the authentication and the 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 { //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)
}
}
When the session expires being the application in background and then comes back to foreground and calls a protected adapter, this part of code is executed:
timeOutController.performSegueWithIdentifier("logOutDueToTimeOut", sender: nil)
The login view loads with success and I can submit again the credentials to login in. The problem is that my application is not longer able to authenticate to the Mobilefirst server, getting 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
It seems that the request does not have a token or is invalid, but I don't get the "authrequired" field in the JSON response so that i can't authenticate again as I did the first time the application authenticates before any Mobilefirst session timeout.
The detailed step by step execution is this one:
- The application shows the login screen to the user
- The user types the credentials
- As a protected adapter is called during this process the mobilefirst server returns a response with "authrequired = true". The isCustomResponse method is automatically called, and returns true.
- As isCustomResponse returns true, The handleChallenge method is called and as the visible viewController is the loginViewController, the first "If" statement is executed, launching the authentication.
- The authentication succeeds and now the user can navigate throughout the application accessing all their protected resources.
- I put the application in background for 10 minutes (Established MobileFirst session timeout in the server).
- I put the application in foreground and start navigating again.
- As the MobileFirst session has expired, once i try to call a protected adapter again the mobilefirst server returns a response with "authrequired = true". The isCustomResponse method is automatically called again, and returns true.
- As isCustomResponse returns true, The handleChallenge method is called and as the visible viewController is NOT the loginViewController, the third "If" statement is executed, showing up the login screen again.
- The user types the credentials.
- The server returns a 403 response. The isCustomResponse method is automatically called but returns false as the response does not contain the "authrequired" field.
Any ideas on how to handle this?