实现 CredentialsValidationSecurityCheck 类

improve this page | report issue


概述

此抽象类可扩展 ExternalizableSecurityCheck,并实现其大多数方法来简化使用过程。 以下两种方法为必需方法:validateCredentialscreateChallenge
CredentialsValidationSecurityCheck 类用于简单流以验证任意凭证,以便授权访问资源。 同时还提供一项内置功能,用于在进行一定次数的尝试后阻止访问。

本教程使用硬编码 PIN 码示例来保护资源,并给予用户 3 次尝试机会(此后将阻止客户机应用程序实例 60 秒)。

先决条件:确保阅读授权概念创建安全性检查教程。

跳转至:

创建安全性检查

创建 Java 适配器,并添加名为 PinCodeAttempts 且可扩展 CredentialsValidationSecurityCheck 的 Java 类。

public class PinCodeAttempts extends CredentialsValidationSecurityCheck {

    @Override
    protected boolean validateCredentials(Map<String, Object> credentials) {
        return false;
    }

    @Override
    protected Map<String, Object> createChallenge() {
        return null;
    }
}

创建验证问题

在触发安全性检查时,会将验证问题发送给客户机。 返回 null 会创建空的验证问题,在某些情况下这可能已足够。
您可以选择使用验证问题返回数据,如要显示的错误消息,或可由客户机使用的任何其他数据。

例如,PinCodeAttempts 会发送预定义的错误消息以及剩余尝试次数。

@Override
    protected Map<String, Object> createChallenge() {
    Map challenge = new HashMap();
    challenge.put("errorMsg",errorMsg);
    challenge.put("remainingAttempts",getRemainingAttempts());
    return challenge;
}

样本应用程序中包含 errorMsg 的实现。

getRemainingAttempts()CredentialsValidationSecurityCheck 继承而来。

验证用户凭证

在客户机发送验证问题的答案时,此答案会作为 Map 传递至 validateCredentials。 如果凭证有效,此方法应实施您的逻辑并返回 true

@Override
    protected boolean validateCredentials(Map<String, Object> credentials) {
    if(credentials!=null &&  credentials.containsKey("pin")){
        String pinCode = credentials.get("pin").toString();

        if(pinCode.equals("1234")){
            return true;
        }
        else {
            errorMsg = "The pin code is not valid.";
        }

    }
    else{
        errorMsg = "The pin code was not provided.";
    }

    //In any other case, credentials are not valid
    return false;

}

配置类

您还可以使用 adapter.xml 文件和 MobileFirst Operations Console 来配置有效的 PIN 码。

创建可扩展 CredentialsValidationSecurityCheckConfig 的新 Java 类。 重要的是要扩展与父安全性检查类匹配的类,以便继承缺省配置。

public class PinCodeConfig extends CredentialsValidationSecurityCheckConfig {

    public String pinCode;

    public PinCodeConfig(Properties properties) {
    super(properties);
        pinCode = getStringProperty("pinCode", properties, "1234");
    }

}

此类中唯一需要的方法是可处理 Properties 实例的构造方法。 get[Type]Property 方法可用于从 adapter.xml 文件检索特定的属性。 如果找不到任何值,那么第三个参数会定义缺省值 (1234)。

您还可以使用 addMessage 方法,在此构造方法中添加错误处理:

public PinCodeConfig(Properties properties) {
    //Make sure to load the parent properties
    super(properties);

    //Load the pinCode property
    pinCode = getStringProperty("pinCode", properties, "1234");

    //Check that the PIN code is at least 4 characters long. Triggers an error.
    if(pinCode.length() < 4) {
        addMessage(errors,"pinCode","pinCode needs to be at least 4 characters");
    }

    //Check that the PIN code is numeric. Triggers warning.
    try {
        int i = Integer.parseInt(pinCode);
    }
    catch(NumberFormatException nfe) {
        addMessage(warnings,"pinCode","PIN code contains non-numeric characters");
    }
}

在主类 (PinCodeAttempts) 中,添加能够装入配置的以下两种方法:

@Override
  public SecurityCheckConfiguration createConfiguration(Properties properties) {
    return new PinCodeConfig(properties);
}
@Override
protected PinCodeConfig getConfiguration() {
    return (PinCodeConfig) super.getConfiguration();
}

您现在可以使用 getConfiguration().pinCode 方法来检索缺省 PIN 码。

您可以修改 validateCredentials 方法来使用配置中的 PIN 码,而不使用硬编码值。

@Override
    protected boolean validateCredentials(Map<String, Object> credentials) {
    if(credentials!=null &&  credentials.containsKey(PINCODE_FIELD)){
        String pinCode = credentials.get(PINCODE_FIELD).toString();

        if(pinCode.equals(getConfiguration().pinCode)){
            return true;
        }
        else {
            errorMsg = "Pin code is not valid. Hint: " + getConfiguration().pinCode;
        }

    }
    else{
        errorMsg = "The pin code was not provided.";
    }

    //In any other case, credentials are not valid
    return false;

}

配置安全性检查

在 adapter.xml 中,添加 <securityCheckDefinition> 元素:

<securityCheckDefinition name="PinCodeAttempts" class="com.sample.PinCodeAttempts">
  <property name="pinCode" defaultValue="1234" description="The valid PIN code"/>
  <property name="maxAttempts" defaultValue="3" description="How many attempts are allowed"/>
  <property name="blockedStateExpirationSec" defaultValue="60" description="How long before the client can try again (seconds)"/>
  <property name="successStateExpirationSec" defaultValue="60" description="How long is a successful state valid for (seconds)"/>
</securityCheckDefinition>

name 属性必须是安全性检查的名称。 将 class 参数设置为先前创建的类。

securityCheckDefinition 可以包含零个或多个 property 元素。 pinCode 属性是 PinCodeConfig 配置类中定义的属性。 其他属性从 CredentialsValidationSecurityCheckConfig 配置类继承而来。

缺省情况下,如果您未在 adapter.xml 文件中指定这些属性,那么将会接收由 CredentialsValidationSecurityCheckConfig 设置的缺省值:

public CredentialsValidationSecurityCheckConfig(Properties properties) {
    super(properties);
    maxAttempts = getIntProperty("maxAttempts", properties, 1);
    attemptingStateExpirationSec = getIntProperty("attemptingStateExpirationSec", properties, 120);
    successStateExpirationSec = getIntProperty("successStateExpirationSec", properties, 3600);
    blockedStateExpirationSec = getIntProperty("blockedStateExpirationSec", properties, 0);
}

CredentialsValidationSecurityCheckConfig 类可定义以下属性:

  • maxAttempts:在达到 failure 之前允许的尝试次数。
  • attemptingStateExpirationSec:客户机必须提供有效凭证并统计尝试次数的时间间隔(秒)。
  • successStateExpirationSec:保持成功登录的时间间隔(秒)。
  • blockedStateExpirationSec:达到 maxAttempts 后阻止客户机的时间间隔(秒)。

请注意,blockedStateExpirationSec 的缺省值将设置为 0:如果客户机发送无效凭证,它可以“在 0 秒后”重试。 这意味着在缺省情况下,将禁用“尝试”功能。

样本安全性检查

下载安全性检查 Maven 项目。

Maven 项目包含 CredentialsValidationSecurityCheck 的实现。

Inclusive terminology note: The Mobile First Platform team is making changes to support the IBM® initiative to replace racially biased and other discriminatory language in our code and content with more inclusive language. While IBM values the use of inclusive language, terms that are outside of IBM's direct influence are sometimes required for the sake of maintaining user understanding. As other industry leaders join IBM in embracing the use of inclusive language, IBM will continue to update the documentation to reflect those changes.
Last modified on June 01, 2020