6 JAF監査エンジンの理解

JAF監査エンジンは、Oracle JAFがOracle JETアプリケーションを監査するときにカスタム監査ルールを呼び出します。

JAF監査エンジンについて

Oracle JAF監査エンジンがサポートするカスタム監査ルールには、標準ルールとフック・ルールの2つのタイプがあります。違いは、標準ルールはファイル・データのJAFによる解析に応じて呼び出され、フック・ルールはJAF監査ライフサイクルのフェーズ(起動時、終了時、またはファイルが最初に読み取られたときなど)に応じて呼び出される点です。

実行時に、Oracle JAFが監査を実行すると、ターゲット・ファイル・セット内の各ファイルがJAF監査エンジンによって解析され、抽象構文ツリー(AST)が作成されます。ASTはJAFをたどり、データ・ノード・イベントは、カスタム監査ルールに登録したリスナー関数に渡されます。

カスタム監査ルールは、定義した構成ファイルに基づいてJAF監査エンジンがロードするJavaScriptファイルとして実装します。実行時に、JAF監査エンジンは、ターゲット・ファイル・セットのASTを生成すると、ロードされたルールにコンテキスト・オブジェクトを渡し、ルールの.jsファイルに実装したASTノード・イベント・リスナーをトリガーします。これにより、監査ルールは、監査済ファイル・セットからの特定のデータに応答できます。

監査エンジンに関する次のリファレンスのトピックでは、標準のノード監査ルールの作成に使用できるノード・リスナー・タイプを示しています。リスナー・タイプは、JETアプリケーション・ソースのファイル・タイプに固有のASTデータ・ノードに対応します。

JAF監査エンジンにより、呼び出されたカスタム監査ルールに、ルールの登録済リスナーに渡されるRuleコンテキスト・オブジェクトへのアクセス権が提供され、データをテストして機能を実行できるようになります。監査の開始時に、監査エンジンは、Registerコンテキスト・オブジェクトをすべてのルールのエントリ・ポイントに渡し、監査に関する情報を取得できるようにします。これらのコンテキスト・オブジェクトの詳細は、次の監査エンジンのリファレンスのトピックを参照してください。

フック・ルールの作成に使用できる監査エンジン・フック・ポイントの詳細は、「フック・ルール呼出しについて」を参照してください。

カスタム監査ルールの構造の理解

Oracle JET Audit Framework (JAF)は、実装するカスタム・ルールの追加によって拡張できます。ルールとは、特定のパブリック関数をエクスポートするJavaScriptファイルです。

監査が実行されると、ターゲット・ファイル・セット内の各ファイルが解析され、抽象構文ツリー(AST)が作成されます。ASTが調査され、ルール内の1つ以上の登録済リスナー関数にノードが渡されます。ルールはJavaScriptファイルとして実装され、実行時にJAFによってnode.jsモジュールとしてロードされます。JAFはASTを分析し、ルール・リスナーを起動する際に、ロードされたルールにコンテキストを渡します。

有効なルールと見なされるためには、ルールで次の4つのメソッドをエクスポートする必要があります:

メソッド 説明
getDescription() 完全で詳細なルールの説明を返します。説明にはHTMLマークアップが含まれる場合があります。
getName() ルール名を返します。
getShortDescription() ルールの簡単な説明/サマリーを返します。
register(Object context) JAFの起動時に呼び出されます。これは、ルール実装へのメインのエントリ・ポイントです。ルールがイベント・ハンドラ関数とともにリスニングするデータのタイプを宣言します。指定されている解析済ASTデータ型またはJAF監査ライフサイクル・フェーズのイベントを含むオブジェクトを返します。

実装してHTMLまたはJSONファイルを監査できるルールのスケルトン・アウトラインを次に示します:

スケルトン・ルール

function getName()
{
   return "my-rule-name" ;
};
 
function  getShortDescription()
{
   return "This a short description of the rule" ;
};
 
function  getDescription()
{
   return "This a much more detailed explanation of the rule, and can include markup." ;
};
 
function  register(context)
{
    // Here the rule registers the type of data that it wants to listen for, together with event handler function(s).
};
 
module.exports = {getName, getDescription, getShortDescription, register};

ノート:

getDescription()によって返されるルールの説明には、HTMLマークアップが含まれることがあります。

ルールでリスニングできる使用可能なイベントのリストは、次を参照してください:

関連項目:

ヒント:

スケルトン・ルールは、次を使用して現在のディレクトリで簡単にスキャフォールドできます
ojaf --initrule myRuleName

必要に応じて、ES6クラスの構文を使用できます。

ES6クラスを返す

class Rule {                             // (name can be anything)
     getName()               {...}
     getDescription()        {...}
     getShortDescription()   {...}
     register(regCtx)        {...}
}

module.exports = Rule;

必要に応じて、クラスを作成するための次のプロトタイプ継承形式も使用でき、Oracle JAFでは関数に対してnewが自動的に実行されます:

クラスを返す

var anyName = function()  {};  // (name is "internal" and can be anything)
anyName.prototype.getName = function()  {...};
anyName.prototype.getShortDescription = function()  {...};
anyName.prototype.getDescription = function()   {...};
anyName.prototype.register(context) {...};
module.exports = anyName ;

監査ルール・エントリ・ポイント・メソッドの構造

監査ルールのメイン・エントリ・ポイントはregister()関数です。定義したノード・ルールの場合、この関数はJAFの起動時にコールされ、ファイル・セットの監査中に見つかった特定のタイプのデータに対してリスナー関数を宣言します。フック・ルールを定義する必要がある場合、この関数を使用して、監査ライフサイクルでJAFによってトリガーされるイベントのリスナーを宣言します。

ノード・ルールの場合、登録されたエントリポイント・メソッドの実装の基本的な目的は、渡されたデータを調べ、1つ以上のIssueオブジェクトを返すことです。この場合、それぞれのオブジェクトに、検出された問題の説明が含まれています。その後、Reporterインスタンスを使用して、レポートする問題を選択できます。問題が検出されない場合は、ルールは単に戻ります。メソッドは、渡されたRegisterコンテキスト・オブジェクトからデータを取得します。

次の擬似コード・サンプルでは、登録されているリスナー・タイプojtagのイベント・リスナーを登録します。ojtagタイプは、特にHTMLおよびJSONファイル用に登録できる多くのリスナー・タイプの1つの例です。リスナー関数の詳細は、「監査ルール・リスナー関数の構造」を参照してください。

function register(regContext)
{

 return {
    ojtag : function(ruleContext, tagName)  // "ojtag" is an example of a registered type - it causes the
    {                                       // function to be called for each DOM element of the form <oj-xxx>
      var issue ;                       
                                        

      // analyze the data passed in the Rule context, and any other supplied args
      . . .

      if (found_a_problem)
      {
        issue =  new  ruleContext.Issue( "describe the problem found" ) ; // create new Issue object
        ruleContext.reporter.addIssue(issue, ruleContext) ;               // pass Issue to the Reporter instance
        }
    };
 }
};

register()関数のサンプルは、Ruleコンテキスト・オブジェクトがIssueインスタンスの作成に使用できるIssueクラスを提供することを示しています。その後、IssueインスタンスはReporterインスタンスに渡され(コンテキストからも使用可能)、レポートする1つ以上の問題を選択します。

ヒント:

通常は、ルールごとに1つの問題をリスニングし、レポートするようカスタム監査ルールを制限することをお薦めします。これにより、必要に応じて、JAF構成ファイルで特定の診断を無効にできます。

現在のファイルが完全に監査されたら、JAFはJAF構成ファイルで指定された形式で問題を出力します。

監査ルール・リスナー関数の構造

監査イベントのリスナー関数は、ルールのregister()関数で定義されます。ファイルの監査時に見つかった特定のタイプのデータに対してリスナー関数を宣言し、ノード・ルールを定義できます。または、監査エンジン・ライフサイクル内のイベントに対してリスナー関数を宣言し、フック・ルールを定義できます。

リスナー関数には、ノード・タイプ・ルール向けの次のシグネチャがあり、一部の引数はruleContextオブジェクトのプロパティでもあります。

function _fnHandler(ruleContext, arg1, arg2) { . . .
      };

フック・ルールの場合、登録されるタイプは監査エンジン・シグナル・イベント(たとえば、endselector)で、引数は使用されません。

ノード・ルールの場合、引数は、登録されたリスナー・タイプによって異なります。

  • arg1は、データ・ノード・トークンを表す文字列です。たとえば、ruleContext.typeojtagまたはtagの場合、これはoj-buttondivなどの文字列を表します。

  • arg2は、arg1を補足するオプションの値である文字列です。たとえば、context.typeattrの場合、これは属性の値を表し、arg1には属性名が含まれます。

ノート:

登録済リスナー・タイプの完全なリストとその引数の説明は、「HTMLおよびJSONルールのリスナー・タイプ」「JavaScript/TypeScriptルールのリスナー・タイプ」および「CSSルールのリスナー・タイプ」を参照してください。フック・タイプ・ルールに対して定義できる登録済タイプについては、「フック・ルール呼出しについて」を参照してください。