Microsoft の Node.js 向け認証拡張機能

Node 用のMicrosoft認証拡張機能は、クライアント アプリケーションがクロスプラットフォーム トークン キャッシュのシリアル化と永続化を実行するためのセキュリティで保護されたメカニズムを提供します。

MSAL ノードでは、開発者はトークン キャッシュを保持するための独自のロジックを実装する必要があります。 MSAL Node 拡張機能は、パブリック クライアント アプリケーション (デスクトップ クライアント、CLI アプリケーションなど) に対して、Windows、Mac、Linux 全体で、堅牢でセキュリティで保護された構成可能なトークン キャッシュの永続性の実装を提供することを目的としています。 複数のプロセスが同時にトークン キャッシュにアクセスするだけでなく、暗号化するためのメカニズムも提供します。

サポートされているプラットフォームは、Windows、Mac、Linux です。

  • Windows - DPAPI は暗号化に使用されます。
  • MAC - MAC KeyChain は npm keytar を介して使用されます。
  • Linux - LibSecret は、npm keytar を介して "Secret Service" に格納するために使用されます。

Code

永続化レイヤーの作成

永続化レイヤーを作成するための API は、対象とするプラットフォームによって異なります。

または、createPersistence API を汎用ラッパーとして使用し、プラットフォーム/OS に基づいて適切な永続化方法を選択することもできます。

const { PublicClientApplication } = require("@azure/msal-node");
const {
  DataProtectionScope,
  PersistenceCreator,
  PersistenceCachePlugin,
} = require("@azure/msal-node-extensions");

const persistence = await PersistenceCreator.createPersistence({
                cachePath: "path/to/cache/file.json",
                dataProtectionScope: DataProtectionScope.CurrentUser,
                serviceName: "test-msal-electron-service",
                accountName: "test-msal-electron-account",
                usePlaintextFileOnLinux: false,
          });
// Use the persistence object to initialize an MSAL PublicClientApplication with cachePlugin
const pca = new PublicClientApplication({
                auth: {
                        clientId: "CLIENT_ID_HERE",
                    },
                cache: {
                        cachePlugin: new PersistenceCachePlugin(persistence);
                    },
                });

または、以下のプラットフォーム固有のオプションを使用できます。


const { FilePersistenceWithDataProtection, DataProtectionScope } = require("@azure/msal-node-extensions");
const { PublicClientApplication } = require("@azure/msal-node");

const cachePath = "path/to/cache/file.json";
const dataProtectionScope = DataProtectionScope.CurrentUser;
const optionalEntropy = ""; //specifies password or other additional entropy used to encrypt the data.
const windowsPersistence = await FilePersistenceWithDataProtection.create(cachePath, dataProtectionScope, optionalEntropy);
// Use the persistence object to initialize an MSAL PublicClientApplication with cachePlugin
const pca = new PublicClientApplication({
                auth: {
                        clientId: "CLIENT_ID_HERE",
                    },
                cache: {
                        cachePlugin: new PersistenceCachePlugin(windowsPersistence);
                    },
                });

  • cachePath は、暗号化されたキャッシュ ファイルが格納されるファイル システム内のパスです。
  • dataProtectionScope は、現在のユーザーまたはローカル コンピューターのデータ保護のスコープを指定します。 データを保護または保護解除するためのキーは必要ありません。 スコープを CurrentUser に設定すると、資格情報で実行されているアプリケーションのみがデータの保護を解除できます。ただし、これは、資格情報で実行されているアプリケーションが保護されたデータにアクセスできることを意味します。 スコープを LocalMachine に設定すると、コンピューター上のすべての完全信頼アプリケーションで、データの保護解除、アクセス、変更を行うことができます。
  • optionalEntropy は、データの暗号化に使用されるパスワードまたはその他の追加エントロピを指定します。

FilePersistenceWithDataProtectionでは、Win32 CryptProtectData API と CryptUnprotectData API が使用されます。 dataProtectionScope または optionalEntropy の詳細については、これらの API のドキュメントを参照してください。

すべてのプラットフォーム

暗号化されていないファイル永続化は、すべてのプラットフォームで機能しますが、推奨されませんが、便宜上提供されます。

const { FilePersistence } = require("@azure/msal-node-extensions");

const filePath = "path/to/cache/file.json";
const filePersistence = await FilePersistence.create(filePath, loggerOptions);
// Pass the persistence to msal config's cachePlugin
const pca = new PublicClientApplication({
    auth: {
            clientId: "CLIENT_ID_HERE",
        },
    cache: {
            cachePlugin: new PersistenceCachePlugin(filePersistence);
        },
  });

ファイルまたはディレクトリが作成されていない場合、 FilePersistence.create() はファイルとパス内の任意のディレクトリを再帰的に作成します。 これは、FilePersistence.tsの動作で確認できます。

コンカレンシーのためにキャッシュ プラグインにロック オプションを渡す

前の手順で作成した永続化オブジェクトを渡して、 PersistenceCachePluginを作成します。

const { PersistenceCachePlugin } = require("@azure/msal-node-extensions");

const persistenceCachePlugin = new PersistenceCachePlugin(windowsPersistence); // or any of the other ones.

複数のプロセスによる同時アクセスをサポートするために、拡張機能はファイル ベースのロックを使用します。 CrossPlatformLockOptionsを使用して、ロック取得の再試行回数と再試行遅延を構成できます。

const {
  PersistenceCreator,
  PersistenceCachePlugin,
} = require("@azure/msal-node-extensions");

const lockOptions = {
    retryNumber: 100,
    retryDelay: 50
}

const persistence = await PersistenceCreator.createPersistence(persistenceConfiguration);
const persistenceCachePlugin = new PersistenceCachePlugin(persistence, lockOptions); // or any of the other ones
const pca = new PublicClientApplication({
    auth: {
            clientId: "CLIENT_ID_HERE",
        },
    cache: {
            cachePlugin: persistenceCachePlugin
        },
    });

MSAL ノード PublicClientApplication 構成での PersistenceCachePlugin の設定 (例を含む)

要約すると、MSAL ノード PersistenceCachePluginで設定できるPublicClientApplicationが作成されたら、次に示すように構成オブジェクトの一部として設定します。

import { PublicClientApplication } from "@azure/msal-node";

const publicClientConfig = {
    auth: {
        clientId: "",
        authority: "",
    },
    cache: {
        cachePlugin: persistenceCachePlugin
    },
};

const pca = new PublicClientApplication(publicClientConfig);

例 (Electron node-js デスクトップ アプリの場合):-

authConfig.js:-

const AAD_ENDPOINT_HOST = "https://login.microsoftonline.com/"; // include the trailing slash
const REDIRECT_URI = "ENTER_REDIRECT_URI";

const cachePath = "path/to/cache/file.json";

/*define persistence config based on the appropriate persistence you are using(e.g- FilePersistenceWithDataProtection, generic PersistenceCreateor, etc)*/

//defining persistence config for PersistenceCreator
const persistenceConfiguration = {
    cachePath,
    dataProtectionScope: DataProtectionScope.CurrentUser,
    serviceName: "test-msal-electron-service",
    accountName: "test-msal-electron-account",
    usePlaintextFileOnLinux: false,
}

  const msalConfig = {
    auth: {
        clientId: "CLIENT_ID_HERE",
        authority: `${AAD_ENDPOINT_HOST}TENANT_ID_HERE`,
    },
    cache: {
        cachePlugin: null // set later in main.js as shown above 
    },
    system: {
        loggerOptions: {
            loggerCallback(loglevel, message, containsPii) {
                console.log(message);
            },
            piiLoggingEnabled: false,
            logLevel: LogLevel.Verbose,
        },
    },
};
...

module.exports = {
  msalConfig: msalConfig,
  protectedResources: protectedResources,
  REDIRECT_URI: REDIRECT_URI,
  persistenceConfiguration
};

Electron 開発者向けノート

電子サンプル: この サンプル は、msal-node-extensions ライブラリを、webpack にバンドルされている電子アプリケーションに統合する方法を示しています。

Electron にこの拡張機能を使用している場合は、次のようなエラーが発生する可能性があります。

Uncaught Exception:
Error: The module
"<path-to-project>\node_modules\...\dpapi.node" was compiled against a different Node.js version using NODE_MODULE_VERSION 85. This version of Node.js requires NODE_MODULE_VERSION 80. Please try re-compiling or re-installing the module...."

このエラーは、Electron プロジェクトと拡張機能 Node.js バージョンの違いが原因である可能性があります。 これは、次の手順でパッケージをビルドし直すことで処理できます。

  • まだインストールしていない場合は、コマンド electron-rebuildを使用してnpm i -D electron-rebuildをインストールします。
  • packages-lock.json が存在する場合は、プロジェクトから削除します
  • ./node_modules/.bin/electron-rebuild を実行します。

Samples

  1. 永続化のための Electron-webpack サンプル
  2. Msal-node 拡張機能のサンプル