ステップアップ認証

improve this page | report issue

概説

リソースは、いくつかのセキュリティー検査によって保護されている場合があります。 そのようなシナリオでは、MobileFirst Server は必要なチャレンジをすべて同時にアプリケーションに送信します。

あるセキュリティー検査が別のセキュリティー検査に依存している場合もあります。 したがって、チャレンジが送信されるタイミングを制御できることが重要になります。
例えば、このチュートリアルで説明するアプリケーションは 2 つのリソースを使用します。リソースはいずれもユーザー名とパスワードによって保護されますが、2 番目のリソースは PIN コードも追加で必要とします。

前提条件: 続ける前に、CredentialsValidationSecurityCheck および UserAuthenticationSecurityCheck のチュートリアルをお読みください。

ジャンプ先:

セキュリティー検査の参照

2 つのセキュリティー検査、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 内に、ユーザーが現在ログイン状態であるかどうかをチェックする便利メソッドを追加します。 このメソッドは、後からチュートリアル内で使用します。

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両方によって保護されているという前提で、このフローは、ユーザーに 2 番目の資格情報 (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 コードを所定のデータベース内でルックアップできるように、現行ユーザーの ID を知る必要があります。

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 はありません。 代わりに、各チャレンジ・ハンドラーがそれぞれのチャレンジを処理します。 この例の場合、2 つのチャレンジ・ハンドラーを個別に登録する必要があります。1 つは、StepUpUserLogin からのチャレンジを処理するもの、もう 1 つは、StepUpPincode からのチャレンジを処理するものです。

ステップアップ・サンプル・アプリケーション

サンプル・アプリケーション

セキュリティー検査

StepUpUserLogin および StepUpPinCode セキュリティー検査は、StepUp Maven プロジェクトの下にある SecurityChecks プロジェクトで入手できます。 ここをクリック してセキュリティー検査 Maven プロジェクトをダウンロードします。

アプリケーション

iOS (Swift)、Android、Windows 8.1/10、Cordova、および Web 用のサンプル・アプリケーションを使用できます。

サンプルの使用法

サンプルの README.md ファイルの指示に従ってください。

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 February 28, 2020