Ekstensi Autentikasi Microsoft untuk Node.js

Ekstensi Autentikasi Microsoft untuk Node menawarkan mekanisme aman bagi aplikasi klien untuk melakukan serialisasi dan persistensi cache token lintas platform.

MSAL Node mengharuskan pengembang untuk menerapkan logika mereka sendiri untuk mempertahankan cache token. Ekstensi MSAL Node bertujuan untuk menyediakan implementasi peristensi cache token yang kuat, aman, dan dapat dikonfigurasi di Windows, Mac, dan Linux untuk aplikasi klien publik (Klien desktop, aplikasi CLI, dll). Ini menyediakan mekanisme untuk mengenkripsi serta mengakses cache token dengan beberapa proses secara bersamaan.

Platform yang didukung Windows, Mac, dan Linux:

  • Windows - DPAPI digunakan untuk enkripsi.
  • MAC - Rantai Kunci MAC digunakan melalui keytar npm.
  • Linux - LibSecret digunakan untuk menyimpan ke "Secret Service" melalui keytar npm.

Code

Membuat lapisan persistensi

API untuk membuat lapisan persistensi akan berbeda berdasarkan platform apa yang Anda targetkan.

Atau, Anda dapat menggunakan createPersistence API dari PersistenceCreator karena ini adalah pembungkus generik dan memilih metode persistensi yang sesuai berdasarkan platform/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);
                    },
                });

Atau, Anda dapat menggunakan opsi khusus platform di bawah ini:


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 adalah jalur dalam sistem file tempat file cache terenkripsi akan disimpan.
  • dataProtectionScope menentukan cakupan perlindungan data, baik pengguna saat ini atau komputer lokal. Anda tidak memerlukan kunci untuk melindungi atau membuka proteksi data. Jika Anda mengatur cakupan ke CurrentUser, hanya aplikasi yang berjalan pada kredensial Anda yang dapat membatalkan perlindungan data; namun, itu berarti bahwa aplikasi apa pun yang berjalan pada kredensial Anda dapat mengakses data yang dilindungi. Jika Anda mengatur cakupan ke LocalMachine, aplikasi kepercayaan penuh apa pun di komputer dapat membatalkan proteksi, mengakses, dan memodifikasi data.
  • optionalEntropy menentukan kata sandi atau entropi tambahan lainnya yang digunakan untuk mengenkripsi data.

FilePersistenceWithDataProtection menggunakan API Win32 CryptProtectData dan CryptUnprotectData. Untuk informasi selengkapnya tentang dataProtectionScope, atau opsionalEntropy, referensikan dokumentasi untuk API tersebut.

Semua platform

Persistensi file yang tidak terenkripsi, yang berfungsi di semua platform, disediakan untuk kenyamanan, meskipun tidak disarankan.

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);
        },
  });

Jika file atau direktori belum dibuat, FilePersistence.create() akan membuat file dan direktori apa pun di jalur secara rekursif. Hal ini dapat dilihat pada FilePersistence.ts

Meneruskan opsi kunci ke plugin Cache untuk konkurensi

Buat PersistenceCachePlugin dengan meneruskan objek persistensi yang dibuat pada langkah sebelumnya.

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

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

Untuk mendukung akses bersamaan dengan beberapa proses, ekstensi menggunakan kunci berbasis file. Anda dapat mengonfigurasi jumlah percobaan ulang dan jeda percobaan ulang untuk perolehan kunci melalui 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
        },
    });

Mengatur PersistenceCachePlugin pada konfigurasi MSAL Node PublicClientApplication (dengan contoh)

Singkatnya, setelah Anda memiliki PersistenceCachePlugin, Anda dapat menetapkannya pada MSAL Node PublicClientApplication dengan menetapkannya sebagai bagian dari objek konfigurasi seperti yang ditunjukkan di bawah ini.

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

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

const pca = new PublicClientApplication(publicClientConfig);

Contoh (untuk aplikasi desktop node-js Electron):-

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
};

Catatan untuk Pengembang Electron

Sampel elektron: Sampel ini menggambarkan cara mengintegrasikan pustaka msal-node-extensions ke aplikasi elektron Anda yang telah dibundel oleh webpack.

Jika Anda menggunakan ekstensi ini untuk Electron, Anda mungkin menghadapi kesalahan yang mirip dengan ini:

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...."

Kesalahan ini mungkin disebabkan oleh perbedaan versi Node.js antara proyek Electron dan ekstensi. Ini dapat ditangani dengan membangun kembali paket dengan langkah-langkah berikut:

  • Instal electron-rebuild dengan perintah npm i -D electron-rebuild jika Anda belum menginstalnya.
  • Hapus packages-lock.json dari proyek Anda jika ada
  • Jalankan ./node_modules/.bin/electron-rebuild

Sampel

  1. Sampel electron-webpack untuk persistensi
  2. Sampel ekstensi Msal-node