Mobilefirst服务器在本机ios应用程序中的会话超时处理后返回错误403

Ire*_*uet 5 authentication ibm-mobilefirst

在本机iOS应用程序中使用基于适配器的身份验证将我的本机ios应用程序(swift)连接到Mobilefirst服务器(7.0).

身份验证机制工作正常,但问题在会话在10分钟后到期时出现.

在这里,您可以看到我处理身份验证和会话超时的代码部分:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

当会话到期时,应用程序在后台运行,然后返回到前台并调用受保护的适配器,这部分代码将被执行:

timeOutController.performSegueWithIdentifier("logOutDueToTimeOut", sender: nil)
Run Code Online (Sandbox Code Playgroud)

登录视图加载成功,我可以再次提交登录凭据.问题是我的应用程序不再能够对Mobilefirst服务器进行身份验证,从而出现此错误:

[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
Run Code Online (Sandbox Code Playgroud)

似乎请求没有令牌或无效,但我没有得到JSON响应中的"authrequired"字段,因此我无法再次进行身份验证,就像我在第一次在任何Mobilefirst会话之前进行身份验证时所做的那样超时.

详细的逐步执行是这样的:

  1. 应用程序向用户显示登录屏幕
  2. 用户键入凭据
  3. 在此过程中调用受保护的适配器时,mobilefirst服务器将返回"authrequired = true"的响应.自动调用isCustomResponse方法,并返回true.
  4. 当isCustomResponse返回true时,调用handleChallenge方法,并且当可见的viewController是loginViewController时,执行第一个"If"语句,启动身份验证.
  5. 身份验证成功,现在用户可以在整个应用程序中导航,访问所有受保护的资源.
  6. 我将应用程序放在后台10分钟(在服务器中建立MobileFirst会话超时).
  7. 我把应用程序放在前台并再次开始导航.
  8. 由于MobileFirst会话已过期,一旦我尝试再次调用受保护的适配器,mobilefirst服务器将返回"authrequired = true"的响应.isCustomResponse方法再次自动调用,并返回true.
  9. 当isCustomResponse返回true时,调用handleChallenge方法,并且由于可见viewController不是loginViewController,执行第三个"If"语句,再次显示登录屏幕.
  10. 用户键入凭据.
  11. 服务器返回403响应.isCustomResponse方法会自动调用,但返回false,因为响应不包含"authrequired"字段.

关于如何处理这个问题的任何想法?

Nat*_*n H 2

我发现您的身份验证流程存在几个问题。

  • 您的步骤从“应用程序向用户显示登录屏幕”开始。您是否对应用程序进行硬编码以从登录屏幕启动?基于适配器的身份验证不支持“抢先”身份验证。这意味着只有挑战才应显示登录屏幕。通常的方法是在应用程序启动期间调用受保护的资源,或者使用loginAPI 来触发挑战。然后您handleChallenge应该显示登录屏幕。
  • “在此过程中调用受保护的适配器”。您在身份验证流程中调用受保护的资源。不好。不要那样做。
  • 如果视图控制器已在屏幕上,您handleChallenge将自动提交凭据。LoginViewController如果用户输入错误的凭据怎么办?它不会循环发送错误的凭据吗?通常,如果LoginViewController已经出现在屏幕上,您只想更新 UI,例如“凭据错误,请重试”。
  • 单击“登录”按钮应该会触发submitAdapterAuthentication。不应触发挑战submitAdapterAuthentication
  • 在你做任何其他事情之前,每一个即将到来的挑战都需要得到解答。这意味着,一旦handleChallenge被调用,您就无法尝试发出任何其他受保护的请求或触发其他一些挑战。

关于您的具体问题,我认为超时后会发生以下情况:

  • handleChallenge被调用,这将打开登录屏幕。
  • 您写道“在此过程中调用受保护的适配器”,但您无法这样做,因为您正面临挑战。
  • 应用程序进入不稳定状态。

如果你遵循我上面写的评论,你应该没问题。但它需要对您的应用程序进行一些架构更改。事件发生的顺序很重要:

  1. 提出受保护的请求。
  2. handleChallenge显示登录表单。
  3. 用户点击提交。
  4. submitAdapterAuthentication

无论是第一次运行、抢先运行还是超时后运行,请确保遵循操作顺序。