Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
A MSAL para Angular pode ser configurada de várias maneiras. Este artigo descreve as opções de configuração disponíveis para o MSAL Angular, incluindo abordagens estáticas e dinâmicas, e fornece exemplos de código para integrar a autenticação ao seu aplicativo. Use este guia para selecionar o método de configuração que melhor atende aos requisitos do aplicativo e fornece uma experiência de entrada perfeita para seus usuários.
Opções de configuração
@azure/msal-angular aceita três objetos de configuração:
-
Configuração: esse é o mesmo objeto de configuração usado para a biblioteca principal
@azure/msal-browser. Todas as opções de configuração podem ser encontradas aqui. -
MsalGuardConfiguration: Um conjunto de opções especificamente para o Angular guard. -
MsalInterceptorConfiguration: um conjunto de opções especificamente para o interceptador Angular.
Configurações específicas do Angular
- Um
interactionTypedeve ser especificado emMsalGuardConfigurationeMsalInterceptorConfiguration, e pode ser definido comoPopupouRedirect. - O objeto
protectedResourceMapemMsalInterceptorConfigurationé usado para proteger rotas. - Um objeto opcional
authRequestpode ser especificado emMsalGuardConfigurationeMsalInterceptorConfigurationpara definir opções adicionais. - Uma cadeia de caracteres opcional
loginFailedRoutepode ser definida emMsalGuardConfiguration. O MSAL Guard redirecionará para essa rota se o logon for necessário e falhar.
Consulte nossos documentos msalInterceptor e MsalGuard para obter mais detalhes sobre configurações, uso e diferenças para MSAL Angular v1.
Configuração para redirecionamentos
Recomendamos importar MsalRedirectComponent e inicializar com o AppComponent se você pretende usar redirecionamentos. Consulte a documentação de redirecionamento para obter mais detalhes.
Nota: A partir da MSAL v3.x, a inicialização do objeto de aplicativo agora é necessária. Consulte o guia de atualização v2-v3 para obter mais detalhes. Para obter detalhes sobre como atualizar para o MSAL Angular v5, consulte o guia de atualização v4-v5.
MsalModule.forRoot
A MsalModule classe contém um método estático que pode ser chamado em seu app.module.ts arquivo:
import { NgModule } from "@angular/core";
import { HTTP_INTERCEPTORS } from "@angular/common/http";
import { AppComponent } from "./app.component";
import { MsalModule, MsalService, MsalGuard, MsalInterceptor, MsalBroadcastService, MsalRedirectComponent } from "@azure/msal-angular";
import { PublicClientApplication, InteractionType, BrowserCacheLocation } from "@azure/msal-browser";
@NgModule({
imports: [
MsalModule.forRoot(
new PublicClientApplication({
// MSAL Configuration
auth: {
clientId: "clientid",
authority: "https://login.microsoftonline.com/common/",
redirectUri: "http://localhost:4200/",
postLogoutRedirectUri: "http://localhost:4200/",
},
cache: {
cacheLocation: BrowserCacheLocation.LocalStorage,
},
system: {
loggerOptions: {
loggerCallback: () => {},
piiLoggingEnabled: false,
},
},
}),
{
interactionType: InteractionType.Popup, // MSAL Guard Configuration
authRequest: {
scopes: ["user.read"],
},
loginFailedRoute: "/login-failed",
},
{
interactionType: InteractionType.Redirect, // MSAL Interceptor Configuration
protectedResourceMap,
}
),
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: MsalInterceptor,
multi: true,
},
MsalGuard,
],
bootstrap: [AppComponent, MsalRedirectComponent],
})
export class AppModule {}
Provedores de fábrica
Você também pode fornecer as opções de configuração por meio de provedores de fábrica.
import { MsalModule, MsalService, MsalInterceptor, MsalInterceptorConfiguration, MsalGuard, MsalGuardConfiguration, MsalBroadcastService, MsalRedirectComponent } from "@azure/msal-angular";
import { IPublicClientApplication, PublicClientApplication, InteractionType, BrowserCacheLocation } from "@azure/msal-browser";
export function MSALInstanceFactory(): IPublicClientApplication {
return new PublicClientApplication({
auth: {
clientId: "00001111-aaaa-2222-bbbb-3333cccc4444",
redirectUri: "http://localhost:4200",
postLogoutRedirectUri: "http://localhost:4200",
},
cache: {
cacheLocation: BrowserCacheLocation.LocalStorage,
},
});
}
export function MSALInterceptorConfigFactory(): MsalInterceptorConfiguration {
const protectedResourceMap = new Map<string, Array<string>>();
protectedResourceMap.set("https://graph.microsoft.com/v1.0/me", ["user.read"]);
return {
interactionType: InteractionType.Redirect,
protectedResourceMap,
};
}
export function MSALGuardConfigFactory(): MsalGuardConfiguration {
return {
interactionType: InteractionType.Redirect,
authRequest: {
scopes: ["user.read"],
},
loginFailedRoute: "./login-failed",
};
}
@NgModule({
imports: [MsalModule],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: MsalInterceptor,
multi: true,
},
{
provide: MSAL_INSTANCE,
useFactory: MSALInstanceFactory,
},
{
provide: MSAL_GUARD_CONFIG,
useFactory: MSALGuardConfigFactory,
},
{
provide: MSAL_INTERCEPTOR_CONFIG,
useFactory: MSALInterceptorConfigFactory,
},
MsalGuard,
MsalBroadcastService,
MsalService,
],
bootstrap: [AppComponent, MsalRedirectComponent],
})
export class AppModule {}
platformBrowserDynamic
Se você precisar configurar dinamicamente o MSAL Angular (por exemplo, com base nos valores retornados de uma API), poderá usar platformBrowserDynamic.
platformBrowserDynamic é uma fábrica de plataforma, usada para inicializar o aplicativo, e é capaz de receber opções de configuração.
platformBrowserDynamic já deve estar presente quando o aplicativo Angular estiver configurado.
Veja a seguir um exemplo de como configurar dinamicamente @azure/msal-angular com platformBrowserDynamic e um arquivo JSON:
app.module.ts
import { MsalModule, MsalInterceptor, MsalService } from "@azure/msal-angular";
@NgModule({
imports: [MsalModule],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: MsalInterceptor,
multi: true,
},
MsalService,
],
bootstrap: [AppComponent],
})
export class AppModule {}
main.ts
import { enableProdMode } from "@angular/core";
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import { AppModule } from "./app/app.module";
import { environment } from "./environments/environment";
import { MSAL_INSTANCE, MSAL_GUARD_CONFIG, MSAL_INTERCEPTOR_CONFIG } from "@azure/msal-angular";
import { PublicClientApplication, Configuration } from "@azure/msal-browser";
if (environment.production) {
enableProdMode();
}
function loggerCallback(logLevel: LogLevel, message: string) {
console.log("MSAL Angular: ", message);
}
fetch("/assets/configuration.json")
.then((response) => response.json())
.then((json) => {
platformBrowserDynamic([
{
provide: MSAL_INSTANCE,
useValue: new PublicClientApplication({
auth: json.msal.auth,
cache: json.msal.cache,
system: {
loggerOptions: {
loggerCallback,
logLevel: LogLevel.Info,
piiLoggingEnabled: false,
},
},
}),
},
{
provide: MSAL_GUARD_CONFIG,
useValue: {
interactionType: json.guard.interactionType,
authRequest: json.guard.authRequest,
loginFailedRoute: json.guard.loginFailedRoute,
} as MsalGuardConfiguration,
},
{
provide: MSAL_INTERCEPTOR_CONFIG,
useValue: {
interactionType: json.interceptor.interactionType,
protectedResourceMap: new Map(json.interceptor.protectedResourceMap),
} as MsalInterceptorConfiguration,
},
])
.bootstrapModule(AppModule)
.catch((err) => console.error(err));
});
src/assets/configuration.json
{
"msal": {
"auth": {
"clientId": "clientid",
"authority": "https://login.microsoftonline.com/common/",
"redirectUri": "http://localhost:4200/",
"postLogoutRedirectUri": "http://localhost:4200/",
"navigateToLoginRequestUrl": true
},
"cache": {
"cacheLocation": "localStorage",
"storeAuthStateInCookie": true
}
},
"guard": {
"interactionType": "redirect",
"authRequest": {
"scopes": ["user.read"]
},
"loginFailedRoute": "/login-failed"
},
"interceptor": {
"interactionType": "redirect",
"protectedResourceMap": [["https://graph.microsoft.com/v1.0/me", ["user.read"]]]
}
}
Configurações dinâmicas usando provedores de fábrica e APP_INITIALIZER
Para configurar dinamicamente o MSAL Angular, você pode usar os Provedores de Fábrica com APP_INITIALIZER.
src/app/config.service.ts
import { Injectable } from "@angular/core";
import { HttpClient, HttpBackend } from "@angular/common/http";
import { map } from "rxjs/operators";
@Injectable({
providedIn: "root",
})
export class ConfigService {
private settings: any;
private http: HttpClient;
constructor(private readonly httpHandler: HttpBackend) {
this.http = new HttpClient(httpHandler);
}
init(endpoint: string): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
this.http
.get(endpoint)
.pipe(map((result) => result))
.subscribe(
(value) => {
this.settings = value;
resolve(true);
},
(error) => {
reject(error);
}
);
});
}
getSettings(key?: string | Array<string>): any {
if (!key || (Array.isArray(key) && !key[0])) {
return this.settings;
}
if (!Array.isArray(key)) {
key = key.split(".");
}
let result = key.reduce((account: any, current: string) => account && account[current], this.settings);
return result;
}
}
src/app/msal-config-dynamic.module.ts
import { InjectionToken, NgModule, APP_INITIALIZER } from "@angular/core";
import { IPublicClientApplication, PublicClientApplication, LogLevel } from "@azure/msal-browser";
import { MsalGuard, MsalInterceptor, MsalBroadcastService, MsalInterceptorConfiguration, MsalModule, MsalService, MSAL_GUARD_CONFIG, MSAL_INSTANCE, MSAL_INTERCEPTOR_CONFIG, MsalGuardConfiguration } from "@azure/msal-angular";
import { HTTP_INTERCEPTORS } from "@angular/common/http";
import { ConfigService } from "./config.service";
const AUTH_CONFIG_URL_TOKEN = new InjectionToken<string>("AUTH_CONFIG_URL");
export function initializerFactory(env: ConfigService, configUrl: string): any {
const promise = env.init(configUrl).then((value) => {
console.log("finished getting configurations dynamically.");
});
return () => promise;
}
export function loggerCallback(logLevel: LogLevel, message: string) {
console.log(message);
}
export function MSALInstanceFactory(config: ConfigService): IPublicClientApplication {
return new PublicClientApplication({
auth: config.getSettings("msal").auth,
cache: config.getSettings("msal").cache,
system: {
loggerOptions: {
loggerCallback,
logLevel: LogLevel.Info,
piiLoggingEnabled: false,
},
},
});
}
export function MSALInterceptorConfigFactory(config: ConfigService): MsalInterceptorConfiguration {
const protectedResourceMap = new Map<string, Array<string>>(config.getSettings("interceptor").protectedResourceMap);
return {
interactionType: config.getSettings("interceptor").interactionType,
protectedResourceMap,
};
}
export function MSALGuardConfigFactory(config: ConfigService): MsalGuardConfiguration {
return {
interactionType: config.getSettings("guard").interactionType,
authRequest: config.getSettings("guard").authRequest,
loginFailedRoute: config.getSettings("guard").loginFailedRoute,
};
}
@NgModule({
providers: [],
imports: [MsalModule],
})
export class MsalConfigDynamicModule {
static forRoot(configFile: string) {
return {
ngModule: MsalConfigDynamicModule,
providers: [
ConfigService,
{ provide: AUTH_CONFIG_URL_TOKEN, useValue: configFile },
{ provide: APP_INITIALIZER, useFactory: initializerFactory, deps: [ConfigService, AUTH_CONFIG_URL_TOKEN], multi: true },
{
provide: MSAL_INSTANCE,
useFactory: MSALInstanceFactory,
deps: [ConfigService],
},
{
provide: MSAL_GUARD_CONFIG,
useFactory: MSALGuardConfigFactory,
deps: [ConfigService],
},
{
provide: MSAL_INTERCEPTOR_CONFIG,
useFactory: MSALInterceptorConfigFactory,
deps: [ConfigService],
},
MsalService,
MsalGuard,
MsalBroadcastService,
{
provide: HTTP_INTERCEPTORS,
useClass: MsalInterceptor,
multi: true,
},
],
};
}
}
src/app/app.module.ts
import { BrowserModule } from "@angular/platform-browser";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { NgModule } from "@angular/core";
import { MatButtonModule } from "@angular/material/button";
import { MatToolbarModule } from "@angular/material/toolbar";
import { MatListModule } from "@angular/material/list";
import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
import { HomeComponent } from "./home/home.component";
import { ProfileComponent } from "./profile/profile.component";
import { HttpClientModule } from "@angular/common/http";
import { MsalRedirectComponent } from "@azure/msal-angular";
import { DetailComponent } from "./detail/detail.component";
import { MsalConfigDynamicModule } from "./msal-config-dynamic.module";
@NgModule({
declarations: [AppComponent, HomeComponent, ProfileComponent, DetailComponent],
imports: [BrowserModule, BrowserAnimationsModule, AppRoutingModule, MatButtonModule, MatToolbarModule, MatListModule, HttpClientModule, MsalConfigDynamicModule.forRoot("assets/configuration.json")],
providers: [],
bootstrap: [AppComponent, MsalRedirectComponent],
})
export class AppModule {}
src/assets/configuration.json
{
"msal": {
"auth": {
"clientId": "clientid",
"authority": "https://login.microsoftonline.com/common/",
"redirectUri": "http://localhost:4200/",
"postLogoutRedirectUri": "http://localhost:4200/",
"navigateToLoginRequestUrl": true
},
"cache": {
"cacheLocation": "localStorage",
"storeAuthStateInCookie": true
}
},
"guard": {
"interactionType": "redirect",
"authRequest": {
"scopes": ["user.read"]
},
"loginFailedRoute": "/login-failed"
},
"interceptor": {
"interactionType": "redirect",
"protectedResourceMap": [["https://graph.microsoft.com/v1.0/me", ["user.read"]]]
}
}
MsalGuard – Solicitação de autenticação dinâmica
O MsalGuard também permite que você altere dinamicamente o authRequest em runtime. Isso permite que você escolha uma autoridade diferente para uma rota ou adicione dinamicamente escopos com base no RouterStateSnapshot.
export function MSALGuardConfigFactory(): MsalGuardConfiguration {
return {
interactionType: InteractionType.Redirect,
authRequest: (authService, state) => {
return {
scopes: state.root.url.some((x) => x.path === "calendar") ? ["user.read", " Calendars.Read"] : ["user.read"],
};
},
loginFailedRoute: "./login-failed",
};
}
Configurações para aplicativos Angular com componentes autônomos
Os aplicativos do Angular que usam componentes autônomos podem ser usados com provedores de fábrica, conforme mostrado acima no arquivo app.config.ts, que é então importado para main.ts para a inicialização.
Consulte nosso exemplo standalone do Angular para saber como usar.
// app.config.ts
import { ApplicationConfig, importProvidersFrom } from "@angular/core";
import { provideRouter } from "@angular/router";
import { routes } from "./app.routes";
import { BrowserModule } from "@angular/platform-browser";
import { provideHttpClient, withInterceptorsFromDi, HTTP_INTERCEPTORS, withFetch, withInterceptors } from "@angular/common/http";
import { provideNoopAnimations } from "@angular/platform-browser/animations";
import { IPublicClientApplication, PublicClientApplication, InteractionType, BrowserCacheLocation, LogLevel } from "@azure/msal-browser";
import { MsalInterceptor, MSAL_INSTANCE, MsalInterceptorConfiguration, MsalGuardConfiguration, MSAL_GUARD_CONFIG, MSAL_INTERCEPTOR_CONFIG, MsalService, MsalGuard, MsalBroadcastService } from "@azure/msal-angular";
export function loggerCallback(logLevel: LogLevel, message: string) {
console.log(message);
}
export function MSALInstanceFactory(): IPublicClientApplication {
return new PublicClientApplication({
auth: {
clientId: "clientid",
authority: "https://login.microsoftonline.com/common/",
redirectUri: "/",
postLogoutRedirectUri: "/",
},
cache: {
cacheLocation: BrowserCacheLocation.LocalStorage,
},
system: {
allowPlatformBroker: false, // Disables WAM Broker
loggerOptions: {
loggerCallback,
logLevel: LogLevel.Info,
piiLoggingEnabled: false,
},
},
});
}
export function MSALInterceptorConfigFactory(): MsalInterceptorConfiguration {
const protectedResourceMap = new Map<string, Array<string>>();
protectedResourceMap.set("https://graph.microsoft.com/v1.0/me", ["user.read"]);
return {
interactionType: InteractionType.Redirect,
protectedResourceMap,
};
}
export function MSALGuardConfigFactory(): MsalGuardConfiguration {
return {
interactionType: InteractionType.Redirect,
authRequest: {
scopes: ["user.read"],
},
loginFailedRoute: "/login-failed",
};
}
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
importProvidersFrom(BrowserModule),
provideNoopAnimations(),
provideHttpClient(withInterceptorsFromDi(), withFetch()),
{
provide: HTTP_INTERCEPTORS,
useClass: MsalInterceptor,
multi: true,
},
{
provide: MSAL_INSTANCE,
useFactory: MSALInstanceFactory,
},
{
provide: MSAL_GUARD_CONFIG,
useFactory: MSALGuardConfigFactory,
},
{
provide: MSAL_INTERCEPTOR_CONFIG,
useFactory: MSALInterceptorConfigFactory,
},
MsalService,
MsalGuard,
MsalBroadcastService,
],
};
// main.ts
import { bootstrapApplication } from "@angular/platform-browser";
import { appConfig } from "./app/app.config";
import { AppComponent } from "./app/app.component";
bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err));