Mobilefirst服务器在本机ios应用程序

时间:2016-05-13 11:10:36

标签: authentication ibm-mobilefirst

我使用Adapter-based authentication in native iOS applications将我的本机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)
    }
}

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

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

登录视图加载成功,我可以再次提交登录凭据。问题是我的应用程序无法再对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

似乎请求没有令牌或无效,但我没有获得" authrequired" JSON响应中的字段,这样我就可以在应用程序第一次在任何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"字段。
  12. 关于如何处理这个的任何想法?

1 个答案:

答案 0 :(得分:2)

我可以在您的身份验证流程中看到几个问题。

  • 您的步骤以“应用程序向用户显示登录屏幕”开头。你是否硬编码应用程序以启动登录屏幕? 基于适配器的身份验证不支持“抢占式”身份验证。仅表示挑战应显示登录屏幕。通常的方法是在应用启动期间调用受保护资源,或使用login API触发质询。然后,您的handleChallenge应显示登录屏幕。
  • “在此过程中调用受保护的适配器”。您正在身份验证流程中调用受保护资源。不好。不要那样做。
  • 如果handleChallenge视图控制器已在屏幕上,则LoginViewController会自动提交凭据。如果用户输入错误的凭据怎么办?它不会在循环中发送错误的凭据吗?通常,如果LoginViewController已经在屏幕上,您只想更新用户界面,例如“错误的凭据,请重试”。
  • 点击“登录”按钮应该是触发submitAdapterAuthentication的内容。挑战不应触发submitAdapterAuthentication
  • 在您做任何其他事情之前,需要回答每一个传入的挑战。这意味着,只要调用handleChallenge,就不能尝试进行任何其他受保护的请求或触发其他一些挑战。

关于您的具体问题,我认为这是在超时后发生的事情:

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

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

  1. 提出受保护的请求。
  2. handleChallenge显示登录表单。
  3. 用户点击提交。
  4. submitAdapterAuthentication
  5. 无论是第一次运行,先发制人还是超时后,都要确保遵循操作顺序。