Jak przeprowadzić migrację aplikacji Node.js z biblioteki ADAL do biblioteki MSAL
Biblioteka Microsoft Authentication Library for Node (MSAL Node) jest teraz zalecanym zestawem SDK do włączania uwierzytelniania i autoryzacji dla aplikacji zarejestrowanych w Platforma tożsamości Microsoft. W tym artykule opisano ważne kroki, które należy wykonać, aby przeprowadzić migrację aplikacji z biblioteki uwierzytelniania usługi Active Directory dla węzła (ADAL Node) do węzła MSAL.
Wymagania wstępne
- Węzeł w wersji 10, 12, 14, 16 lub 18. Zobacz notatkę dotyczącą obsługi wersji
Aktualizowanie ustawień rejestracji aplikacji
Podczas pracy z węzłem biblioteki ADAL prawdopodobnie używano punktu końcowego usługi Azure AD w wersji 1.0. Aplikacje migrujące z biblioteki ADAL do biblioteki MSAL powinny przełączyć się do punktu końcowego usługi Azure AD w wersji 2.0.
Instalowanie i importowanie biblioteki MSAL
- zainstaluj pakiet biblioteki MSAL Node za pomocą narzędzia npm:
npm install @azure/msal-node
- Następnie zaimportuj węzeł MSAL w kodzie:
const msal = require('@azure/msal-node');
- Na koniec odinstaluj pakiet ADAL Node i usuń wszystkie odwołania w kodzie:
npm uninstall adal-node
Inicjowanie biblioteki MSAL
W węźle biblioteki ADAL zainicjujesz AuthenticationContext
obiekt, który następnie uwidacznia metody, których można użyć w różnych przepływach uwierzytelniania (na przykład acquireTokenWithAuthorizationCode
w przypadku aplikacji internetowych). Podczas inicjowania jedynym obowiązkowym parametrem jest identyfikator URI urzędu:
var adal = require('adal-node');
var authorityURI = "https://login.microsoftonline.com/common";
var authenticationContex = new adal.AuthenticationContext(authorityURI);
W węźle BIBLIOTEKi MSAL istnieją dwie alternatywy: jeśli tworzysz aplikację mobilną lub aplikację klasyczną PublicClientApplication
, utworzysz wystąpienie obiektu. Konstruktor oczekuje obiektu konfiguracji, który zawiera clientId
parametr co najmniej. Biblioteka MSAL domyślnie określa identyfikator URI https://login.microsoftonline.com/common
urzędu, jeśli go nie określisz.
const msal = require('@azure/msal-node');
const pca = new msal.PublicClientApplication({
auth: {
clientId: "YOUR_CLIENT_ID"
}
});
Uwaga
Jeśli używasz https://login.microsoftonline.com/common
urzędu w wersji 2.0, możesz zezwolić użytkownikom na logowanie się przy użyciu dowolnej organizacji firmy Microsoft Entra lub osobistego konta Microsoft (MSA). Jeśli w węźle BIBLIOTEKi MSAL chcesz ograniczyć logowanie do dowolnego konta Microsoft Entra (takie samo zachowanie jak w przypadku węzła biblioteki ADAL), użyj https://login.microsoftonline.com/organizations
zamiast tego.
Z drugiej strony, jeśli tworzysz aplikację internetową lub aplikację demona, tworzysz wystąpienie ConfidentialClientApplication
obiektu. W przypadku takich aplikacji należy również podać poświadczenia klienta, takie jak klucz tajny klienta lub certyfikat:
const msal = require('@azure/msal-node');
const cca = new msal.ConfidentialClientApplication({
auth: {
clientId: "YOUR_CLIENT_ID",
clientSecret: "YOUR_CLIENT_SECRET"
}
});
Zarówno PublicClientApplication
, jak i ConfidentialClientApplication
, w przeciwieństwie do biblioteki AuthenticationContext
ADAL, jest powiązany z identyfikatorem klienta. Oznacza to, że jeśli masz różne identyfikatory klientów, których chcesz użyć w aplikacji, musisz utworzyć wystąpienie nowego wystąpienia biblioteki MSAL dla każdego z nich. Zobacz, aby uzyskać więcej informacji: Inicjowanie węzła biblioteki MSAL
Konfigurowanie biblioteki MSAL
Podczas kompilowania aplikacji na Platforma tożsamości Microsoft aplikacja będzie zawierać wiele parametrów związanych z uwierzytelnianiem. W węźle AuthenticationContext
biblioteki ADAL obiekt ma ograniczoną liczbę parametrów konfiguracji, za pomocą których można utworzyć wystąpienie, podczas gdy pozostałe parametry zawieszają się swobodnie w kodzie (na przykład clientSecret):
var adal = require('adal-node');
var authority = "https://login.microsoftonline.com/YOUR_TENANT_ID"
var validateAuthority = true,
var cache = null;
var authenticationContext = new adal.AuthenticationContext(authority, validateAuthority, cache);
authority
: adres URL identyfikujący urząd tokenuvalidateAuthority
: funkcja, która uniemożliwia kodowi żądanie tokenów od potencjalnie złośliwego urzęducache
: ustawia pamięć podręczną tokenu używaną przez to wystąpienie AuthenticationContext. Jeśli ten parametr nie jest ustawiony, zostanie użyta wartość domyślna w pamięci podręcznej pamięci
Z drugiej strony węzeł MSAL używa obiektu konfiguracji typu Configuration. Zawiera on następujące właściwości:
const msal = require('@azure/msal-node');
const msalConfig = {
auth: {
clientId: "YOUR_CLIENT_ID",
authority: "https://login.microsoftonline.com/YOUR_TENANT_ID",
clientSecret: "YOUR_CLIENT_SECRET",
knownAuthorities: [],
},
cache: {
// your implementation of caching
},
system: {
loggerOptions: { /** logging related options */ }
}
}
const cca = new msal.ConfidentialClientApplication(msalConfig);
W związku z możliwą różnicą biblioteka MSAL nie ma flagi wyłączania weryfikacji urzędu, a urzędy są zawsze weryfikowane domyślnie. Biblioteka MSAL porównuje żądaną władzę z listą urzędów znanych firmie Microsoft lub listą urzędów określonych w konfiguracji. Zobacz, aby uzyskać więcej informacji: Opcje konfiguracji
Przełączanie do interfejsu API biblioteki MSAL
Większość metod publicznych w węźle biblioteki ADAL ma odpowiedniki w węźle BIBLIOTEKi MSAL:
ADAL | BIBLIOTEKA MSAL | Uwagi |
---|---|---|
acquireToken |
acquireTokenSilent |
Zmieniono nazwę, a teraz oczekuje obiektu konta |
acquireTokenWithAuthorizationCode |
acquireTokenByCode |
|
acquireTokenWithClientCredentials |
acquireTokenByClientCredential |
|
acquireTokenWithRefreshToken |
acquireTokenByRefreshToken |
Przydatne do migrowania prawidłowych tokenów odświeżania |
acquireTokenWithDeviceCode |
acquireTokenByDeviceCode |
Teraz abstrakcji pozyskiwania kodu użytkownika (patrz poniżej) |
acquireTokenWithUsernamePassword |
acquireTokenByUsernamePassword |
Jednak niektóre metody w węźle biblioteki ADAL są przestarzałe, a biblioteka MSAL Node oferuje nowe metody:
ADAL | BIBLIOTEKA MSAL | Uwagi |
---|---|---|
acquireUserCode |
Nie dotyczy | Scalone z acquireTokeByDeviceCode (patrz powyżej) |
Nie dotyczy | acquireTokenOnBehalfOf |
Nowa metoda, która abstrakcji przepływu OBO |
acquireTokenWithClientCertificate |
Nie dotyczy | Nie są już potrzebne, ponieważ certyfikaty są przypisywane podczas inicjowania (zobacz opcje konfiguracji) |
Nie dotyczy | getAuthCodeUrl |
Nowa metoda, która abstrakcyjnie autoryzuje konstrukcję adresu URL punktu końcowego |
Używanie zakresów zamiast zasobów
Ważna różnica między punktami końcowymi w wersji 1.0 a 2.0 dotyczy sposobu uzyskiwania dostępu do zasobów. W węźle biblioteki ADAL należy najpierw zarejestrować uprawnienie w portalu rejestracji aplikacji, a następnie zażądać tokenu dostępu dla zasobu (takiego jak Microsoft Graph), jak pokazano poniżej:
authenticationContext.acquireTokenWithAuthorizationCode(
req.query.code,
redirectUri,
resource, // e.g. 'https://graph.microsoft.com'
clientId,
clientSecret,
function (err, response) {
// do something with the authentication response
}
);
Węzeł MSAL obsługuje tylko punkt końcowy w wersji 2.0 . Punkt końcowy w wersji 2.0 wykorzystuje model skoncentrowany na zakresie w celu uzyskania dostępu do zasobów. W związku z tym podczas żądania tokenu dostępu dla zasobu należy również określić zakres dla tego zasobu:
const tokenRequest = {
code: req.query.code,
scopes: ["https://graph.microsoft.com/User.Read"],
redirectUri: REDIRECT_URI,
};
pca.acquireTokenByCode(tokenRequest).then((response) => {
// do something with the authentication response
}).catch((error) => {
console.log(error);
});
Jedną z zalet modelu skoncentrowanego na zakresie jest możliwość korzystania z zakresów dynamicznych. Podczas tworzenia aplikacji korzystających z wersji 1.0 konieczne było zarejestrowanie pełnego zestawu uprawnień (nazywanych zakresami statycznymi) wymaganych przez aplikację, aby użytkownik wyraził zgodę w momencie logowania. W wersji 2.0 można użyć parametru zakresu, aby zażądać uprawnień w momencie ich użycia (w związku z tym zakresy dynamiczne). Dzięki temu użytkownik może udzielić przyrostowej zgody na zakresy. Jeśli więc na początku chcesz, aby użytkownik zalogował się do aplikacji i nie potrzebujesz żadnego rodzaju dostępu, możesz to zrobić. Jeśli później potrzebujesz możliwości odczytania kalendarza użytkownika, możesz zażądać zakresu kalendarza w metodach acquireToken i uzyskać zgodę użytkownika. Zobacz, aby uzyskać więcej informacji: Zasoby i zakresy
Używanie obietnic zamiast wywołań zwrotnych
W węźle biblioteki ADAL wywołania zwrotne są używane dla dowolnej operacji po pomyślnym uwierzytelnieniu i uzyskana jest odpowiedź:
var context = new AuthenticationContext(authorityUrl, validateAuthority);
context.acquireTokenWithClientCredentials(resource, clientId, clientSecret, function(err, response) {
if (err) {
console.log(err);
} else {
// do something with the authentication response
}
});
W węźle BIBLIOTEKi MSAL zamiast tego są używane obietnice:
const cca = new msal.ConfidentialClientApplication(msalConfig);
cca.acquireTokenByClientCredential(tokenRequest).then((response) => {
// do something with the authentication response
}).catch((error) => {
console.log(error);
});
Można również użyć składni async/await , która jest dostarczana z ES8:
try {
const authResponse = await cca.acquireTokenByCode(tokenRequest);
} catch (error) {
console.log(error);
}
Włącz rejestrowanie
W węźle biblioteki ADAL rejestrowanie jest konfigurowane oddzielnie w dowolnym miejscu w kodzie:
var adal = require('adal-node');
//PII or OII logging disabled. Default Logger does not capture any PII or OII.
adal.logging.setLoggingOptions({
log: function (level, message, error) {
console.log(message);
if (error) {
console.log(error);
}
},
level: logging.LOGGING_LEVEL.VERBOSE, // provide the logging level
loggingWithPII: false // Determine if you want to log personal identification information. The default value is false.
});
W węźle biblioteki MSAL rejestrowanie jest częścią opcji konfiguracji i jest tworzone przy użyciu inicjowania wystąpienia biblioteki MSAL Node:
const msal = require('@azure/msal-node');
const msalConfig = {
auth: {
// authentication related parameters
},
cache: {
// cache related parameters
},
system: {
loggerOptions: {
loggerCallback(loglevel, message, containsPii) {
console.log(message);
},
piiLoggingEnabled: false,
logLevel: msal.LogLevel.Verbose,
}
}
}
const cca = new msal.ConfidentialClientApplication(msalConfig);
Włączanie buforowania tokenów
W węźle biblioteki ADAL była dostępna opcja importowania pamięci podręcznej tokenu w pamięci. Pamięć podręczna tokenu jest używana jako parametr podczas inicjowania AuthenticationContext
obiektu:
var MemoryCache = require('adal-node/lib/memory-cache');
var cache = new MemoryCache();
var authorityURI = "https://login.microsoftonline.com/common";
var context = new AuthenticationContext(authorityURI, true, cache);
Węzeł MSAL domyślnie używa pamięci podręcznej tokenu w pamięci. Nie trzeba jawnie go importować; Pamięć podręczna tokenu ConfidentialClientApplication
w pamięci jest uwidaczniona w ramach klas i PublicClientApplication
.
const msalTokenCache = publicClientApplication.getTokenCache();
Co ważne, poprzednia pamięć podręczna tokenów z węzłem biblioteki ADAL nie będzie można przenieść do węzła MSAL, ponieważ schematy pamięci podręcznej są niezgodne. Można jednak użyć prawidłowych tokenów odświeżania uzyskanych wcześniej z węzła biblioteki ADAL w środowisku MSAL Node. Aby uzyskać więcej informacji, zobacz sekcję dotyczącą tokenów odświeżania .
Możesz również zapisać pamięć podręczną na dysku, podając własną wtyczkę pamięci podręcznej. Wtyczka pamięci podręcznej musi zaimplementować interfejs ICachePlugin
. Podobnie jak rejestrowanie, buforowanie jest częścią opcji konfiguracji i jest tworzone przy użyciu inicjowania wystąpienia biblioteki MSAL Node:
const msal = require('@azure/msal-node');
const msalConfig = {
auth: {
// authentication related parameters
},
cache: {
cachePlugin // your implementation of cache plugin
},
system: {
// logging related options
}
}
const msalInstance = new ConfidentialClientApplication(msalConfig);
Przykładową wtyczkę pamięci podręcznej można zaimplementować w następujący sposób:
const fs = require('fs');
// Call back APIs which automatically write and read into a .json file - example implementation
const beforeCacheAccess = async (cacheContext) => {
cacheContext.tokenCache.deserialize(await fs.readFile(cachePath, "utf-8"));
};
const afterCacheAccess = async (cacheContext) => {
if(cacheContext.cacheHasChanged) {
await fs.writeFile(cachePath, cacheContext.tokenCache.serialize());
}
};
// Cache Plugin
const cachePlugin = {
beforeCacheAccess,
afterCacheAccess
};
Jeśli tworzysz publiczne aplikacje klienckie, takie jak aplikacje klasyczne, rozszerzenia uwierzytelniania firmy Microsoft dla środowiska Node oferują bezpieczne mechanizmy dla aplikacji klienckich do wykonywania serializacji i trwałości międzyplatformowej pamięci podręcznej tokenów. Obsługiwane platformy to Systemy Windows, Mac i Linux.
Uwaga
Rozszerzenia uwierzytelniania firmy Microsoft dla środowiska Node nie są zalecane w przypadku aplikacji internetowych, ponieważ mogą prowadzić do problemów ze skalowaniem i wydajnością. Zamiast tego zaleca się utrwalanie pamięci podręcznej w sesji.
Usuwanie logiki wokół tokenów odświeżania
W węźle biblioteki ADAL tokeny odświeżania (RT) zostały ujawnione, umożliwiając opracowywanie rozwiązań dotyczących używania tych tokenów przez buforowanie ich i używanie acquireTokenWithRefreshToken
metody . Typowe scenariusze, w których RTs są szczególnie istotne:
- Długotrwałe usługi, które wykonują akcje, w tym odświeżanie pulpitów nawigacyjnych w imieniu użytkowników, którzy nie są już połączeni.
- Scenariusze WebFarm umożliwiające klientowi przełączenie rt do usługi internetowej (buforowanie odbywa się po stronie klienta, zaszyfrowany plik cookie, a nie po stronie serwera).
Węzeł MSAL wraz z innymi listami MSALS nie uwidacznia tokenów odświeżania ze względów bezpieczeństwa. Zamiast tego biblioteka MSAL obsługuje odświeżanie tokenów. W związku z tym nie trzeba już tworzyć logiki. Można jednak użyć wcześniej uzyskanych (i nadal prawidłowych) tokenów odświeżania z pamięci podręcznej węzła biblioteki ADAL, aby uzyskać nowy zestaw tokenów z węzłem MSAL. W tym celu węzeł MSAL oferuje element acquireTokenByRefreshToken
, który jest odpowiednikiem metody biblioteki acquireTokenWithRefreshToken
ADAL Node:
var msal = require('@azure/msal-node');
const config = {
auth: {
clientId: "ENTER_CLIENT_ID",
authority: "https://login.microsoftonline.com/ENTER_TENANT_ID",
clientSecret: "ENTER_CLIENT_SECRET"
}
};
const cca = new msal.ConfidentialClientApplication(config);
const refreshTokenRequest = {
refreshToken: "", // your previous refresh token here
scopes: ["https://graph.microsoft.com/.default"],
forceCache: true,
};
cca.acquireTokenByRefreshToken(refreshTokenRequest).then((response) => {
console.log(response);
}).catch((error) => {
console.log(error);
});
Aby uzyskać więcej informacji, zapoznaj się z przykładem migracji węzła biblioteki ADAL do biblioteki MSAL Node.
Uwaga
Zalecamy zniszczenie starszej pamięci podręcznej tokenów biblioteki ADAL Node po wykorzystaniu nadal prawidłowych tokenów odświeżania w celu uzyskania nowego zestawu tokenów przy użyciu metody biblioteki MSAL Node acquireTokenByRefreshToken
, jak pokazano powyżej.
Obsługa błędów i wyjątków
W przypadku korzystania z węzła MSAL najczęstszym typem błędu może być interaction_required
błąd. Ten błąd jest często rozwiązywany przez zainicjowanie interakcyjnego monitu o uzyskanie tokenu. Na przykład w przypadku używania metody acquireTokenSilent
, jeśli nie ma buforowanych tokenów odświeżania, węzeł MSAL nie będzie mógł uzyskać tokenu dostępu w trybie dyskretnym. Podobnie internetowy interfejs API, do którego próbujesz uzyskać dostęp, może mieć wprowadzone zasady dostępu warunkowego, co wymaga od użytkownika przeprowadzenia uwierzytelniania wieloskładnikowego (MFA). W takich przypadkach obsługa interaction_required
błędu przez wyzwolenie spowoduje wyświetlenie monitu użytkownika o uwierzytelnianie wieloskładnikowe acquireTokenByCode
, co umożliwi mu pełne filtrowanie.
Kolejnym typowym błędem, który może wystąpić, jest consent_required
, który występuje, gdy uprawnienia wymagane do uzyskania tokenu dostępu dla chronionego zasobu nie są wyrażane przez użytkownika. Podobnie jak w interaction_required
systemie rozwiązanie błędu consent_required
często inicjuje interakcyjny monit o pozyskiwanie tokenu acquireTokenByCode
przy użyciu metody .
Uruchom aplikację
Po zakończeniu zmian uruchom aplikację i przetestuj scenariusz uwierzytelniania:
npm start
Przykład: uzyskiwanie tokenów za pomocą węzła biblioteki ADAL a węzła BIBLIOTEKi MSAL
Poniższy fragment kodu przedstawia poufną aplikację internetową klienta w strukturze Express.js. Wykonuje logowanie, gdy użytkownik osiągnie trasę /auth
uwierzytelniania , uzyskuje token dostępu dla programu Microsoft Graph za pośrednictwem /redirect
trasy, a następnie wyświetla zawartość wspomnianego tokenu.
Korzystanie z węzła biblioteki ADAL | Korzystanie z biblioteki MSAL Node |
|
|