增强认证

improve this page | report issue

概述

可通过多项安全性检查保护资源。 在此类场景中,MobileFirst Server 会同时将所有相关验证问题发送到应用程序。

一项安全性检查也可依赖于另一项安全性检查。 因此,重要的是能够控制何时发送验证问题。
例如,本教程描述具有用户名和密码保护的两个资源的应用程序,其中第二个资源还需要额外的 PIN 码。

先决条件:在继续前先阅读 CredentialsValidationSecurityCheckUserAuthenticationSecurityCheck 教程。

跳转至:

引用安全性检查

创建两项安全性检查:StepUpPinCodeStepUpUserLogin。 它们的初始实施与凭证验证用户认证教程中描述的实施相同。

在此示例中,StepUpPinCode 依赖于 ** StepUpUserLogin。 仅在成功登录到 StepUpUserLogin 之后要求用户输入 PIN 码。 出于此目的,StepUpPinCode 必须能够引用** StepUpUserLogin 类。

MobileFirst 框架提供注释以插入引用。
StepUpPinCode 类中的类级别添加:

@SecurityCheckReference
private transient StepUpUserLogin userLogin;

重要信息:需要在相同适配器内绑定这两种安全性检查实施。

为解析此引用,该框架会查找具有相应类的安全性检查,并将其引用插入到从属安全性检查。
如果存在相同类的多项安全性检查,那么注释具有可选的 name 参数,可用于指定所引用检查的唯一名称。

状态机

扩展 CredentialsValidationSecurityCheck(包含 StepUpPinCodeStepUpUserLogin)的所有类均继承一个简单状态机。 在任何指定时刻,安全性检查都可处于以下一种状态:

  • STATE_ATTEMPTING:已发送验证问题并且安全性检查正在等待客户机响应。 在此状态期间将保持尝试计数。
  • STATE_SUCCESS:已成功验证凭证。
  • STATE_BLOCKED:已到达最大尝试次数并且检查处于已锁定状态。

可使用继承的 getState() 方法获取当前状态。

StepUpUserLogin 中,添加 convenience 方法以检查用户当前是否已登录。 本教程中稍后将使用此方法。

public boolean isLoggedIn(){
    return this.getState().equals(STATE_SUCCESS);
}

Authorize 方法

SecurityCheck 接口定义名为 authorize 的方法。 此方法负责实施安全性检查的主逻辑,例如,发送验证问题或验证请求。
StepUpPinCode 扩展的类 CredentialsValidationSecurityCheck 已包含此方法的实施。 但是,在此情况下,目标是在开始 authorize 方法的缺省行为之前检查 StepUpUserLogin 的状态。

要执行此操作,请覆盖 authorize 方法:

@Override
public void authorize(Set<String> scope, Map<String, Object> credentials, HttpServletRequest request, AuthorizationResponse response) {
    if(userLogin.isLoggedIn()){
        super.authorize(scope, credentials, request, response);
    }
}

此实施检查 StepUpUserLogin 引用的当前状态:

  • 如果状态为 STATE_SUCCESS(用户已登录),那么安全性检查的正常流程将继续。
  • 如果 StepUpUserLogin 为任何其他状态,那么不执行任何操作:不发送验证问题,既不成功也不失败。

假定 StepUpPinCodeStepUpUserLogin 共同保护资源,那么此流程会确保在提示输入次要凭证(PIN 码)之前用户已登录。 即使已激活这两项安全性检查,客户机也从不会同时收到两个验证问题。

或者,如果 StepUpPinCode 保护资源(该框架将仅激活此安全性检查),那么您可以更改 authorize 实现以手动触发 StepUpUserLogin

@Override
public void authorize(Set<String> scope, Map<String, Object> credentials, HttpServletRequest request, AuthorizationResponse response) {
    if(userLogin.isLoggedIn()){
        //If StepUpUserLogin is successful, continue the normal processing of StepUpPinCode
        super.authorize(scope, credentials, request, response);
    } else {
        //In any other case, process StepUpUserLogin instead.
        userLogin.authorize(scope, credentials, request, response);
    }
}

检索当前用户

StepUpPinCode 安全性检查中,主要了解当前用户的标识,从而可在某些数据库中查找此用户的 PIN 码。

StepUpUserLogin 安全性检查中,添加以下方法以从授权上下文获取当前用户:

public AuthenticatedUser getUser(){
    return authorizationContext.getActiveUser();
}

StepUpPinCode 中,然后可使用 userLogin.getUser() 方法从 StepUpUserLogin 安全性检查获取当前用户,并针对此特定用户检查有效的 PIN 码:

@Override
    protected boolean validateCredentials(Map<String, Object> credentials) {
    //Get the correct PIN code from the database
    User user = userManager.getUser(userLogin.getUser().getId());

    if(credentials!=null &&  credentials.containsKey(PINCODE_FIELD)){
        String pinCode = credentials.get(PINCODE_FIELD).toString();

        if(pinCode.equals(user.getPinCode())){
            errorMsg = null;
            return true;
        }
        else{
            errorMsg = "Wrong credentials. Hint: " + user.getPinCode();
        }
    }
    return false;
}

验证问题处理程序

在客户机端,无特殊 API 来处理多个步骤。 每个验证问题处理程序都会处理自己的验证问题。 在此示例中,必须注册两个单独的验证问题处理程序:一个用于处理来自 StepUpUserLogin 的验证问题,一个用于处理来自 StepUpPincode 的验证问题。

设置样本应用程序

样本应用程序

安全性检查

StepUpUserLoginStepUpPinCode 安全性检查可用于 StepUp Maven 项目下的 SecurityChecks 项目。 单击以下载安全性检查 Maven 项目。

应用程序

样本应用程序可用于 iOS (Swift)、Android、Windows 8.1/10、Cordova 和 Web。

样本用法

请遵循样本的 README.md 文件获取指示信息。

Last modified on October 05, 2017