@azure/msal-angular 4.0.11 → 4.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.beachballrc +3 -0
- package/.editorconfig +16 -0
- package/.eslintrc.json +3 -0
- package/CHANGELOG.json +2315 -0
- package/CHANGELOG.md +869 -0
- package/FAQ.md +182 -0
- package/angular.json +51 -0
- package/docs/angular-universal.md +64 -0
- package/docs/configuration.md +609 -0
- package/docs/errors.md +89 -0
- package/docs/events.md +262 -0
- package/docs/initialization.md +206 -0
- package/docs/known-issues.md +19 -0
- package/docs/logging.md +47 -0
- package/docs/msal-guard.md +208 -0
- package/docs/msal-interceptor.md +160 -0
- package/docs/multi-tenant.md +90 -0
- package/docs/performance.md +50 -0
- package/docs/public-apis.md +29 -0
- package/docs/redirects.md +257 -0
- package/docs/security.md +4 -0
- package/docs/ssosilent.md +84 -0
- package/docs/v0-v1-upgrade-guide.md +61 -0
- package/docs/v1-v2-upgrade-guide.md +70 -0
- package/docs/v2-v3-upgrade-guide.md +52 -0
- package/docs/v3-v4-upgrade-guide.md +36 -0
- package/karma.conf.js +44 -0
- package/ng-package.json +7 -0
- package/package.json +56 -26
- package/src/IMsalService.ts +34 -0
- package/src/constants.ts +20 -0
- package/src/msal.broadcast.config.ts +8 -0
- package/src/msal.broadcast.service.spec.ts +471 -0
- package/src/msal.broadcast.service.ts +84 -0
- package/src/msal.guard.config.ts +27 -0
- package/src/msal.guard.spec.ts +525 -0
- package/src/msal.guard.ts +290 -0
- package/src/msal.interceptor.config.ts +39 -0
- package/src/msal.interceptor.spec.ts +1168 -0
- package/src/msal.interceptor.ts +388 -0
- package/src/msal.module.ts +51 -0
- package/src/msal.navigation.client.spec.ts +96 -0
- package/src/msal.navigation.client.ts +59 -0
- package/src/msal.redirect.component.spec.ts +64 -0
- package/src/msal.redirect.component.ts +26 -0
- package/src/msal.service.spec.ts +468 -0
- package/src/msal.service.ts +104 -0
- package/src/packageMetadata.ts +3 -0
- package/{public-api.d.ts → src/public-api.ts} +35 -17
- package/src/test.ts +19 -0
- package/tsconfig.json +25 -0
- package/tsconfig.lib.json +27 -0
- package/tsconfig.lib.prod.json +10 -0
- package/tsconfig.spec.json +17 -0
- package/typedoc.json +10 -0
- package/IMsalService.d.ts +0 -17
- package/constants.d.ts +0 -5
- package/esm2020/IMsalService.mjs +0 -6
- package/esm2020/azure-msal-angular.mjs +0 -5
- package/esm2020/constants.mjs +0 -10
- package/esm2020/msal.broadcast.config.mjs +0 -6
- package/esm2020/msal.broadcast.service.mjs +0 -66
- package/esm2020/msal.guard.config.mjs +0 -6
- package/esm2020/msal.guard.mjs +0 -218
- package/esm2020/msal.interceptor.config.mjs +0 -6
- package/esm2020/msal.interceptor.mjs +0 -270
- package/esm2020/msal.module.mjs +0 -46
- package/esm2020/msal.navigation.client.mjs +0 -53
- package/esm2020/msal.redirect.component.mjs +0 -31
- package/esm2020/msal.service.mjs +0 -88
- package/esm2020/packageMetadata.mjs +0 -4
- package/esm2020/public-api.mjs +0 -18
- package/fesm2015/azure-msal-angular.mjs +0 -762
- package/fesm2015/azure-msal-angular.mjs.map +0 -1
- package/fesm2020/azure-msal-angular.mjs +0 -758
- package/fesm2020/azure-msal-angular.mjs.map +0 -1
- package/index.d.ts +0 -5
- package/msal.broadcast.config.d.ts +0 -3
- package/msal.broadcast.service.d.ts +0 -19
- package/msal.guard.config.d.ts +0 -9
- package/msal.guard.d.ts +0 -43
- package/msal.interceptor.config.d.ts +0 -13
- package/msal.interceptor.d.ts +0 -70
- package/msal.module.d.ts +0 -13
- package/msal.navigation.client.d.ts +0 -19
- package/msal.redirect.component.d.ts +0 -15
- package/msal.service.d.ts +0 -33
- package/packageMetadata.d.ts +0 -2
package/docs/events.md
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# Events in MSAL Angular
|
|
2
|
+
|
|
3
|
+
Before you start here, make sure you understand how to [initialize the application object](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-angular/docs/initialization.md).
|
|
4
|
+
|
|
5
|
+
`@azure/msal-angular` uses the event system exposed by `@azure/msal-browser`, which emits events related to auth and MSAL, and can be used for updating UI, showing error messages, and so on.
|
|
6
|
+
|
|
7
|
+
## Consuming events in your app
|
|
8
|
+
|
|
9
|
+
Events in `@azure/msal-angular` are managed by the `MsalBroadcastService`, and are available by subscribing to the `msalSubject$` observable on the `MsalBroadcastService`.
|
|
10
|
+
|
|
11
|
+
Here is an example of how you can consume the emitted events in your application:
|
|
12
|
+
```javascript
|
|
13
|
+
import { MsalBroadcastService } from '@azure/msal-angular';
|
|
14
|
+
import { EventMessage, EventType } from '@azure/msal-browser';
|
|
15
|
+
|
|
16
|
+
export class AppComponent implements OnInit, OnDestroy {
|
|
17
|
+
private readonly _destroying$ = new Subject<void>();
|
|
18
|
+
|
|
19
|
+
constructor(
|
|
20
|
+
//...
|
|
21
|
+
private msalBroadcastService: MsalBroadcastService
|
|
22
|
+
) {}
|
|
23
|
+
|
|
24
|
+
ngOnInit(): void {
|
|
25
|
+
this.msalBroadcastService.msalSubject$
|
|
26
|
+
.pipe(
|
|
27
|
+
// Optional filtering of events.
|
|
28
|
+
filter((msg: EventMessage) => msg.eventType === EventType.LOGIN_SUCCESS),
|
|
29
|
+
takeUntil(this._destroying$)
|
|
30
|
+
)
|
|
31
|
+
.subscribe((result: EventMessage) => {
|
|
32
|
+
// Do something with the result
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
ngOnDestroy(): void {
|
|
37
|
+
this._destroying$.next(null);
|
|
38
|
+
this._destroying$.complete();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Note that you may need to cast the `result.payload` as a specific type to prevent compilation errors. The payload type will depend on the event, and can be found in our documentation [here](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/events.md).
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
ngOnInit(): void {
|
|
47
|
+
this.msalBroadcastService.msalSubject$
|
|
48
|
+
.pipe(
|
|
49
|
+
filter((msg: EventMessage) => msg.eventType === EventType.LOGIN_SUCCESS),
|
|
50
|
+
)
|
|
51
|
+
.subscribe((result: EventMessage) => {
|
|
52
|
+
// Casting payload as AuthenticationResult to access account
|
|
53
|
+
const payload = result.payload as AuthenticationResult;
|
|
54
|
+
this.authService.instance.setActiveAccount(payload.account);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
For the full example of using events, please see our sample [here](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/samples/msal-angular-samples/angular-modules-sample/src/app/home/home.component.ts).
|
|
60
|
+
|
|
61
|
+
## Table of events
|
|
62
|
+
|
|
63
|
+
For more information about the `EventMessage` object, including the full table of events currently emitted by `@azure/msal-browser` (including descriptions and related payloads), please see the documentation [here](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/events.md).
|
|
64
|
+
|
|
65
|
+
## Handling errors with events
|
|
66
|
+
|
|
67
|
+
As the `EventError` in `EventMessage` is defined as `AuthError | Error | null`, an error should be validated as the correct type before accessing specific properties on it.
|
|
68
|
+
|
|
69
|
+
See the example below of how an error can be cast to `AuthError` to avoid TypeScript errors:
|
|
70
|
+
|
|
71
|
+
```javascript
|
|
72
|
+
import { MsalBroadcastService } from '@azure/msal-angular';
|
|
73
|
+
import { EventMessage, EventType } from '@azure/msal-browser';
|
|
74
|
+
|
|
75
|
+
export class AppComponent implements OnInit, OnDestroy {
|
|
76
|
+
private readonly _destroying$ = new Subject<void>();
|
|
77
|
+
|
|
78
|
+
constructor(
|
|
79
|
+
//...
|
|
80
|
+
private msalBroadcastService: MsalBroadcastService
|
|
81
|
+
) {}
|
|
82
|
+
|
|
83
|
+
ngOnInit(): void {
|
|
84
|
+
this.msalBroadcastService.msalSubject$
|
|
85
|
+
.pipe(
|
|
86
|
+
// Optional filtering of events
|
|
87
|
+
filter((msg: EventMessage) => msg.eventType === EventType.LOGIN_FAILURE),
|
|
88
|
+
takeUntil(this._destroying$)
|
|
89
|
+
)
|
|
90
|
+
.subscribe((result: EventMessage) => {
|
|
91
|
+
if (result.error instanceof AuthError) {
|
|
92
|
+
// Do something with the error
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
ngOnDestroy(): void {
|
|
98
|
+
this._destroying$.next(null);
|
|
99
|
+
this._destroying$.complete();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
An example of error handling can also be found on our [MSAL Angular B2C Sample](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/samples/msal-angular-samples/angular-b2c-sample/src/app/app.component.ts#L129).
|
|
105
|
+
|
|
106
|
+
## Syncing logged in state across tabs and windows
|
|
107
|
+
|
|
108
|
+
If you would like to update your UI when a user logs in or out of your app in a different tab or window you can subscribe to the `ACCOUNT_ADDED` and `ACCOUNT_REMOVED` events. The payload will be the `AccountInfo` object that was added or removed.
|
|
109
|
+
|
|
110
|
+
```javascript
|
|
111
|
+
import { MsalService, MsalBroadcastService } from '@azure/msal-angular';
|
|
112
|
+
import { EventMessage, EventType } from '@azure/msal-browser';
|
|
113
|
+
|
|
114
|
+
export class AppComponent implements OnInit, OnDestroy {
|
|
115
|
+
private readonly _destroying$ = new Subject<void>();
|
|
116
|
+
|
|
117
|
+
constructor(
|
|
118
|
+
//...
|
|
119
|
+
private authService: MsalService,
|
|
120
|
+
private msalBroadcastService: MsalBroadcastService
|
|
121
|
+
) {}
|
|
122
|
+
|
|
123
|
+
ngOnInit(): void {
|
|
124
|
+
this.authService.instance.enableAccountStorageEvents(); // Register the storage listener that will be emitting the events
|
|
125
|
+
this.msalBroadcastService.msalSubject$
|
|
126
|
+
.pipe(
|
|
127
|
+
// Optional filtering of events
|
|
128
|
+
filter((msg: EventMessage) => msg.eventType === EventType.ACCOUNT_ADDED || msg.eventType === EventType.ACCOUNT_REMOVED),
|
|
129
|
+
takeUntil(this._destroying$)
|
|
130
|
+
)
|
|
131
|
+
.subscribe((result: EventMessage) => {
|
|
132
|
+
if (this.authService.msalInstance.getAllAccounts().length === 0) {
|
|
133
|
+
// Account logged out in a different tab, redirect to homepage
|
|
134
|
+
window.location.pathname = "/";
|
|
135
|
+
} else {
|
|
136
|
+
// Update UI to show user is signed in. result.payload contains the account that was logged in
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
ngOnDestroy(): void {
|
|
142
|
+
this._destroying$.next(null);
|
|
143
|
+
this._destroying$.complete();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
A full example can also be found in our [samples](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/samples/msal-angular-samples/angular-modules-sample/src/app/app.component.ts).
|
|
149
|
+
|
|
150
|
+
## The inProgress$ Observable
|
|
151
|
+
|
|
152
|
+
The `inProgress$` observable is also handled by the `MsalBroadcastService`, and should be subscribed to when application needs to know the status of interactions, particularly to check that interactions are completed. We recommend checking that the status of interactions is `InteractionStatus.None` before functions involving user accounts.
|
|
153
|
+
|
|
154
|
+
Note that the last / most recent `InteractionStatus` will also be available when subscribing to the `inProgress$` observable.
|
|
155
|
+
|
|
156
|
+
See the example below for its use. A full example can also be found in our [samples](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/samples/msal-angular-samples/angular-modules-sample/src/app/home/home.component.ts#L29). A full list of interaction statuses can be found [here](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/src/utils/BrowserConstants.ts#L87).
|
|
157
|
+
|
|
158
|
+
```js
|
|
159
|
+
import { Component, OnInit, Inject, OnDestroy } from '@angular/core';
|
|
160
|
+
import { MsalBroadcastService} from '@azure/msal-angular';
|
|
161
|
+
import { InteractionStatus } from '@azure/msal-browser';
|
|
162
|
+
import { Subject } from 'rxjs';
|
|
163
|
+
import { filter, takeUntil } from 'rxjs/operators';
|
|
164
|
+
|
|
165
|
+
@Component({
|
|
166
|
+
selector: 'app-root',
|
|
167
|
+
templateUrl: './app.component.html',
|
|
168
|
+
styleUrls: ['./app.component.css']
|
|
169
|
+
})
|
|
170
|
+
export class AppComponent implements OnInit, OnDestroy {
|
|
171
|
+
private readonly _destroying$ = new Subject<void>();
|
|
172
|
+
|
|
173
|
+
constructor(
|
|
174
|
+
private msalBroadcastService: MsalBroadcastService
|
|
175
|
+
) {}
|
|
176
|
+
|
|
177
|
+
ngOnInit(): void {
|
|
178
|
+
this.msalBroadcastService.inProgress$
|
|
179
|
+
.pipe(
|
|
180
|
+
// Filtering for all interactions to be completed
|
|
181
|
+
filter((status: InteractionStatus) => status === InteractionStatus.None),
|
|
182
|
+
takeUntil(this._destroying$)
|
|
183
|
+
)
|
|
184
|
+
.subscribe(() => {
|
|
185
|
+
// Do something related to user accounts or UI here
|
|
186
|
+
})
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
ngOnDestroy(): void {
|
|
190
|
+
this._destroying$.next(null);
|
|
191
|
+
this._destroying$.complete();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Optional `MsalBroadcastService` Configurations
|
|
198
|
+
|
|
199
|
+
The `MsalBroadcastService` can be optionally configured to replay past events when subscribed to. By default, events that are emitted after the `MsalBroadcastService` is subscribed to are available. There may be instances where events prior to subscription are needed. By providing a configuration for the `MsalBroadcastService` and setting the `eventsToReplay` parameter to a number, that number of past events will be available upon subscription.
|
|
200
|
+
|
|
201
|
+
For more information about replaying events, see the RxJS docs on ReplaySubjects [here](https://rxjs.dev/api/index/class/ReplaySubject).
|
|
202
|
+
|
|
203
|
+
The `MsalBroadcastService` can be configured in the app.module.ts file as follows:
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
// app.module.ts
|
|
207
|
+
import { NgModule } from '@angular/core';
|
|
208
|
+
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
|
209
|
+
import { AppComponent } from './app.component';
|
|
210
|
+
import { MsalModule, MsalService, MsalGuard, MsalInterceptor, MsalBroadcastService, MsalRedirectComponent, MSAL_BROADCAST_CONFIG } from "@azure/msal-angular"; // Import MsalBroadcastService and MSAL_BROADCAST_CONFIG here
|
|
211
|
+
import { PublicClientApplication, InteractionType, BrowserCacheLocation } from "@azure/msal-browser";
|
|
212
|
+
|
|
213
|
+
@NgModule({
|
|
214
|
+
imports: [
|
|
215
|
+
MsalModule.forRoot( new PublicClientApplication({ // MSAL Configuration
|
|
216
|
+
auth: {
|
|
217
|
+
clientId: "clientid",
|
|
218
|
+
authority: "https://login.microsoftonline.com/common/",
|
|
219
|
+
redirectUri: "http://localhost:4200/",
|
|
220
|
+
postLogoutRedirectUri: "http://localhost:4200/",
|
|
221
|
+
navigateToLoginRequestUrl: true
|
|
222
|
+
},
|
|
223
|
+
cache: {
|
|
224
|
+
cacheLocation : BrowserCacheLocation.LocalStorage,
|
|
225
|
+
storeAuthStateInCookie: true, // set to true for IE 11
|
|
226
|
+
},
|
|
227
|
+
system: {
|
|
228
|
+
loggerOptions: {
|
|
229
|
+
loggerCallback: () => {},
|
|
230
|
+
piiLoggingEnabled: false
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}), {
|
|
234
|
+
interactionType: InteractionType.Popup, // MSAL Guard Configuration
|
|
235
|
+
authRequest: {
|
|
236
|
+
scopes: ['user.read']
|
|
237
|
+
},
|
|
238
|
+
loginFailedRoute: "/login-failed"
|
|
239
|
+
}, {
|
|
240
|
+
interactionType: InteractionType.Redirect, // MSAL Interceptor Configuration
|
|
241
|
+
protectedResourceMap
|
|
242
|
+
})
|
|
243
|
+
],
|
|
244
|
+
providers: [
|
|
245
|
+
{
|
|
246
|
+
provide: HTTP_INTERCEPTORS,
|
|
247
|
+
useClass: MsalInterceptor,
|
|
248
|
+
multi: true
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
provide: MSAL_BROADCAST_CONFIG, // Add configuration to providers here
|
|
252
|
+
useValue: {
|
|
253
|
+
eventsToReplay: 2 // Set how many events you want to replay when subscribing
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
MsalGuard,
|
|
257
|
+
MsalBroadcastService // Ensure the MsalBroadcastService is provided
|
|
258
|
+
],
|
|
259
|
+
bootstrap: [AppComponent, MsalRedirectComponent]
|
|
260
|
+
})
|
|
261
|
+
export class AppModule {}
|
|
262
|
+
```
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Initialization of MSAL Angular
|
|
2
|
+
|
|
3
|
+
Before using `@azure/msal-angular`, [register an application in Azure AD](https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app) to get your `clientId`.
|
|
4
|
+
|
|
5
|
+
In this document:
|
|
6
|
+
- [Initialization of MSAL](#initialization-of-msal-angular)
|
|
7
|
+
- [Include and initialize the MSAL module in your app module](#include-and-initialize-the-msal-module-in-your-app-module)
|
|
8
|
+
- [Secure the routes in your application](#secure-the-routes-in-your-application)
|
|
9
|
+
- [Get tokens for Web API calls](#get-tokens-for-web-api-calls)
|
|
10
|
+
- [Subscribe to events](#subscribe-to-events)
|
|
11
|
+
- [Next Steps](#next-steps)
|
|
12
|
+
|
|
13
|
+
## Include and initialize the MSAL module in your app module
|
|
14
|
+
|
|
15
|
+
Import `MsalModule` into app.module.ts. To initialize MSAL module you are required to pass the clientId of your application which you can get from the application registration.
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import { NgModule } from '@angular/core';
|
|
19
|
+
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
|
|
20
|
+
import { AppComponent } from './app.component';
|
|
21
|
+
import { MsalModule, MsalService, MsalGuard, MsalInterceptor, MsalBroadcastService, MsalRedirectComponent } from "@azure/msal-angular";
|
|
22
|
+
import { PublicClientApplication, InteractionType, BrowserCacheLocation } from "@azure/msal-browser";
|
|
23
|
+
|
|
24
|
+
@NgModule({
|
|
25
|
+
imports: [
|
|
26
|
+
MsalModule.forRoot( new PublicClientApplication({ // MSAL Configuration
|
|
27
|
+
auth: {
|
|
28
|
+
clientId: "Your client ID",
|
|
29
|
+
authority: "Your authority",
|
|
30
|
+
redirectUri: "Your redirect Uri",
|
|
31
|
+
},
|
|
32
|
+
cache: {
|
|
33
|
+
cacheLocation : BrowserCacheLocation.LocalStorage,
|
|
34
|
+
storeAuthStateInCookie: true, // Deprecated, will be removed in future version
|
|
35
|
+
},
|
|
36
|
+
system: {
|
|
37
|
+
loggerOptions: {
|
|
38
|
+
loggerCallback: () => {},
|
|
39
|
+
piiLoggingEnabled: false
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}), {
|
|
43
|
+
interactionType: InteractionType.Redirect, // MSAL Guard Configuration
|
|
44
|
+
}, {
|
|
45
|
+
interactionType: InteractionType.Redirect, // MSAL Interceptor Configuration
|
|
46
|
+
})
|
|
47
|
+
],
|
|
48
|
+
providers: [
|
|
49
|
+
{
|
|
50
|
+
provide: HTTP_INTERCEPTORS,
|
|
51
|
+
useClass: MsalInterceptor,
|
|
52
|
+
multi: true
|
|
53
|
+
},
|
|
54
|
+
MsalService,
|
|
55
|
+
MsalGuard,
|
|
56
|
+
MsalBroadcastService
|
|
57
|
+
],
|
|
58
|
+
bootstrap: [AppComponent, MsalRedirectComponent]
|
|
59
|
+
})
|
|
60
|
+
export class AppModule {}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Secure the routes in your application
|
|
64
|
+
|
|
65
|
+
You can add authentication to secure specific routes in your application by just adding `canActivate: [MsalGuard]` to your route definition. It can be added at the parent or child routes. When a user visits these routes, the library will prompt the user to authenticate.
|
|
66
|
+
|
|
67
|
+
See our [`MsalGuard` doc](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-angular/docs/msal-guard.md) for more details on configuration and considerations, including using additional interfaces.
|
|
68
|
+
|
|
69
|
+
See this example of a route defined with the `MsalGuard`:
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
import { NgModule } from '@angular/core';
|
|
73
|
+
import { Routes, RouterModule } from '@angular/router';
|
|
74
|
+
import { HomeComponent } from './home/home.component';
|
|
75
|
+
import { ProfileComponent } from './profile/profile.component';
|
|
76
|
+
import { MsalGuard } from '@azure/msal-angular';
|
|
77
|
+
|
|
78
|
+
const routes: Routes = [
|
|
79
|
+
{
|
|
80
|
+
path: 'profile',
|
|
81
|
+
component: ProfileComponent,
|
|
82
|
+
canActivate: [MsalGuard]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
path: '',
|
|
86
|
+
component: HomeComponent
|
|
87
|
+
},
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
@NgModule({
|
|
91
|
+
imports: [RouterModule.forRoot(routes)],
|
|
92
|
+
exports: [RouterModule]
|
|
93
|
+
})
|
|
94
|
+
export class AppRoutingModule { }
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Get tokens for Web API calls
|
|
98
|
+
|
|
99
|
+
`@azure/msal-angular` allows you to add an Http interceptor (`MsalInterceptor`) in your `app.module.ts` as follows. The `MsalInterceptor` will obtain tokens and add them to all your Http requests in API calls based on the `protectedResourceMap`. See our [MsalInterceptor doc](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-angular/docs/msal-interceptor.md) for more details on configuration and use.
|
|
100
|
+
|
|
101
|
+
```js
|
|
102
|
+
import { NgModule } from '@angular/core';
|
|
103
|
+
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
|
104
|
+
import { AppComponent } from './app.component';
|
|
105
|
+
import { MsalModule, MsalService, MsalGuard, MsalInterceptor, MsalBroadcastService, MsalRedirectComponent } from "@azure/msal-angular";
|
|
106
|
+
import { PublicClientApplication, InteractionType, BrowserCacheLocation } from "@azure/msal-browser";
|
|
107
|
+
|
|
108
|
+
@NgModule({
|
|
109
|
+
imports: [
|
|
110
|
+
MsalModule.forRoot( new PublicClientApplication({ // MSAL Configuration
|
|
111
|
+
auth: {
|
|
112
|
+
clientId: "Your client ID",
|
|
113
|
+
authority: "Your authority",
|
|
114
|
+
redirectUri: "Your redirect Uri",
|
|
115
|
+
},
|
|
116
|
+
cache: {
|
|
117
|
+
cacheLocation : BrowserCacheLocation.LocalStorage,
|
|
118
|
+
storeAuthStateInCookie: true, // Deprecated, will be removed in future version
|
|
119
|
+
},
|
|
120
|
+
system: {
|
|
121
|
+
loggerOptions: {
|
|
122
|
+
loggerCallback: () => {},
|
|
123
|
+
piiLoggingEnabled: false
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}), {
|
|
127
|
+
interactionType: InteractionType.Redirect, // MSAL Guard Configuration
|
|
128
|
+
}, {
|
|
129
|
+
interactionType: InteractionType.Redirect, // MSAL Interceptor Configuration
|
|
130
|
+
protectedResourceMap: new Map([
|
|
131
|
+
['https://graph.microsoft.com/v1.0/me', ['user.read']],
|
|
132
|
+
['https://api.myapplication.com/users/*', ['customscope.read']],
|
|
133
|
+
['http://localhost:4200/about/', null]
|
|
134
|
+
])
|
|
135
|
+
})
|
|
136
|
+
],
|
|
137
|
+
providers: [
|
|
138
|
+
{
|
|
139
|
+
provide: HTTP_INTERCEPTORS,
|
|
140
|
+
useClass: MsalInterceptor,
|
|
141
|
+
multi: true
|
|
142
|
+
},
|
|
143
|
+
MsalService,
|
|
144
|
+
MsalGuard,
|
|
145
|
+
MsalBroadcastService
|
|
146
|
+
],
|
|
147
|
+
bootstrap: [AppComponent, MsalRedirectComponent]
|
|
148
|
+
})
|
|
149
|
+
export class AppModule {}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Using the `MsalInterceptor` is optional. You may wish to explicitly acquire tokens using the acquireToken APIs instead.
|
|
153
|
+
|
|
154
|
+
Please note that the `MsalInterceptor` is provided for your convenience and may not fit all use cases. We encourage you to write your own interceptor if you have specific needs that are not addressed by the `MsalInterceptor`.
|
|
155
|
+
|
|
156
|
+
## Subscribe to events
|
|
157
|
+
|
|
158
|
+
MSAL provides an event system, which emits events related to auth and MSAL, and can be subscribed to as below. To use events, the `MsalBroadcastService` should be added to your constructor in your component/service.
|
|
159
|
+
|
|
160
|
+
### 1. How to subscribe to events
|
|
161
|
+
|
|
162
|
+
```js
|
|
163
|
+
import { EventMessage, EventType } from '@azure/msal-browser';
|
|
164
|
+
import { filter } from 'rxjs/operators';
|
|
165
|
+
|
|
166
|
+
this.msalBroadcastService.msalSubject$
|
|
167
|
+
.pipe(
|
|
168
|
+
filter((msg: EventMessage) => msg.eventType === EventType.LOGIN_SUCCESS)
|
|
169
|
+
)
|
|
170
|
+
.subscribe((result) => {
|
|
171
|
+
// do something here
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### 2. Available events
|
|
176
|
+
|
|
177
|
+
The list of events available to MSAL can be found in the [`@azure/msal-browser` event documentation.](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/events.md)
|
|
178
|
+
|
|
179
|
+
### 3. Unsubscribing
|
|
180
|
+
|
|
181
|
+
It is extremely important to unsubscribe. Implement `ngOnDestroy()` in your component and unsubscribe.
|
|
182
|
+
|
|
183
|
+
```js
|
|
184
|
+
import { EventMessage, EventType } from '@azure/msal-browser';
|
|
185
|
+
import { filter, Subject, takeUntil } from 'rxjs';
|
|
186
|
+
|
|
187
|
+
private readonly _destroying$ = new Subject<void>();
|
|
188
|
+
|
|
189
|
+
this.msalBroadcastService.msalSubject$
|
|
190
|
+
.pipe(
|
|
191
|
+
filter((msg: EventMessage) => msg.eventType === EventType.LOGIN_SUCCESS),
|
|
192
|
+
takeUntil(this._destroying$)
|
|
193
|
+
)
|
|
194
|
+
.subscribe((result) => {
|
|
195
|
+
this.checkAccount();
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
ngOnDestroy(): void {
|
|
199
|
+
this._destroying$.next(null);
|
|
200
|
+
this._destroying$.complete();
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
# Next Steps
|
|
205
|
+
|
|
206
|
+
You are ready to use `@azure/msal-angular` [public APIs](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-angular/docs/public-apis.md)!
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Known issues for MSAL Angular
|
|
2
|
+
|
|
3
|
+
## 2.0.0
|
|
4
|
+
* MSAL Guard's `CanLoad` does not interactively prompt for login. This will be addressed in a future release.
|
|
5
|
+
|
|
6
|
+
## 2.0.0-beta.6
|
|
7
|
+
* Due to a security fix, the `MsalCustomNavigationClient` will not navigate client-side when `navigateToLoginRequestUrl` is set to true and handling redirects. This will be addressed in a future release.
|
|
8
|
+
|
|
9
|
+
## 2.0.0-beta.4
|
|
10
|
+
* When the MSAL Guard is used on the page used for the redirect URI, the `code=` hash may remain in the url. This is addressed in `2.0.0-beta.5`, except when the MSAL Guard is used for `canLoad`. To mitigate this issue, applications should not put the MSAL Guard on the page used for the redirect URI.
|
|
11
|
+
|
|
12
|
+
## 2.0.0-alpha.3
|
|
13
|
+
* MSAL Guard's `Canload` interface has a return type of `Observable<boolean|UrlTree>`, which is incompatible with the Angular 9 `CanLoad` base type. This is addressed in version `2.0.0-alpha.4`.
|
|
14
|
+
|
|
15
|
+
## 2.0.0-alpha.0
|
|
16
|
+
* Warnings related to `minimatch` and `path`: These warnings should not cause any problems and will be addressed in a future release.
|
|
17
|
+
* IE11 is not supported: This is not currently supported in this version, but will be addressed in a future release.
|
|
18
|
+
|
|
19
|
+
Please see the `@azure/msal-browser` [FAQ](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/FAQ.md#why-is-there-no-access-token-returned-from-acquiretokensilent) for additional known issues.
|
package/docs/logging.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Logging in MSAL Angular
|
|
2
|
+
|
|
3
|
+
The logger definition has the following properties:
|
|
4
|
+
|
|
5
|
+
1. correlationId
|
|
6
|
+
1. logLevel
|
|
7
|
+
* logLevels include: `Error`, `Warning`, `Info`, `Trace`, and `Verbose`
|
|
8
|
+
1. piiLoggingEnabled
|
|
9
|
+
|
|
10
|
+
You can enable logging in your app as shown below:
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
import { LogLevel, PublicClientApplication } from '@azure/msal-browser';
|
|
14
|
+
|
|
15
|
+
export function loggerCallback(logLevel: LogLevel, message: string) {
|
|
16
|
+
console.log(message);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@NgModule({
|
|
20
|
+
imports: [
|
|
21
|
+
MsalModule.forRoot(new PublicClientApplication({
|
|
22
|
+
auth: {
|
|
23
|
+
clientId: 'Your client ID',
|
|
24
|
+
},
|
|
25
|
+
system: {
|
|
26
|
+
loggerOptions: {
|
|
27
|
+
loggerCallback,
|
|
28
|
+
piiLoggingEnabled: true,
|
|
29
|
+
logLevel: LogLevel.Info
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}))
|
|
33
|
+
]
|
|
34
|
+
})
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The `logger` can also be set dynamically by using `MsalService.setLogger()`.
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
this.authService.setLogger(new Logger({
|
|
41
|
+
loggerCallback: (logLevel, message, piiEnabled) => {
|
|
42
|
+
console.log('MSAL Logging: ', message);
|
|
43
|
+
},
|
|
44
|
+
piiLoggingEnabled: false,
|
|
45
|
+
logLevel: LogLevel.Info
|
|
46
|
+
}));
|
|
47
|
+
```
|