Skip to content

Commit 80968c4

Browse files
committed
adding all identity platform docs to collab branch
1 parent c699714 commit 80968c4

12 files changed

+2682
-1
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
---
2+
title: Avoid page reloads (MSAL.js)
3+
description: Learn how to avoid page reloads when acquiring and renewing tokens silently using the Microsoft Authentication Library for JavaScript (MSAL.js).
4+
author: OwenRichards1
5+
manager: CelesteDG
6+
ms.author: owenrichards
7+
ms.custom: devx-track-js
8+
ms.date: 05/29/2019
9+
ms.reviewer: saeeda
10+
ms.service: active-directory
11+
ms.subservice: develop
12+
ms.topic: how-to
13+
#Customer intent: As an application developer, I want to learn about avoiding page reloads so I can create more robust applications.
14+
---
15+
16+
# Avoid page reloads when acquiring and renewing tokens silently using MSAL.js
17+
The Microsoft Authentication Library for JavaScript (MSAL.js) uses hidden `iframe` elements to acquire and renew tokens silently in the background. Microsoft Entra ID returns the token back to the registered `redirect_uri` specified in the token request(by default this is the app's root page). Since the response is a 302, it results in the HTML corresponding to the `redirect_uri` getting loaded in the `iframe`. Usually the app's `redirect_uri` is the root page and this causes it to reload.
18+
19+
In other cases, if navigating to the app's root page requires authentication, it might lead to nested `iframe` elements or `X-Frame-Options: deny` error.
20+
21+
Since MSAL.js cannot dismiss the 302 issued by Microsoft Entra ID and is required to process the returned token, it cannot prevent the `redirect_uri` from getting loaded in the `iframe`.
22+
23+
To avoid the entire app reloading again or other errors caused due to this, please follow these workarounds.
24+
25+
## Specify different HTML for the iframe
26+
27+
Set the `redirect_uri` property on config to a simple page, that does not require authentication. You have to make sure that it matches with the `redirect_uri` registered in Microsoft Entra admin center. This will not affect user's login experience as MSAL saves the start page when user begins the login process and redirects back to the exact ___location after login is completed.
28+
29+
## Initialization in your main app file
30+
31+
If your app is structured such that there is one central JavaScript file that defines the app's initialization, routing, and other stuff, you can conditionally load your app modules based on whether the app is loading in an `iframe` or not. For example:
32+
33+
In AngularJS: app.js
34+
35+
```javascript
36+
// Check that the window is an iframe and not popup
37+
if (window !== window.parent && !window.opener) {
38+
angular.module('todoApp', ['ui.router', 'MsalAngular'])
39+
.config(['$httpProvider', 'msalAuthenticationServiceProvider','$locationProvider', function ($httpProvider, msalProvider,$locationProvider) {
40+
msalProvider.init(
41+
// msal configuration
42+
);
43+
44+
$locationProvider.html5Mode(false).hashPrefix('');
45+
}]);
46+
}
47+
else {
48+
angular.module('todoApp', ['ui.router', 'MsalAngular'])
49+
.config(['$stateProvider', '$httpProvider', 'msalAuthenticationServiceProvider', '$locationProvider', function ($stateProvider, $httpProvider, msalProvider, $locationProvider) {
50+
$stateProvider.state("Home", {
51+
url: '/Home',
52+
controller: "homeCtrl",
53+
templateUrl: "/App/Views/Home.html",
54+
}).state("TodoList", {
55+
url: '/TodoList',
56+
controller: "todoListCtrl",
57+
templateUrl: "/App/Views/TodoList.html",
58+
requireLogin: true
59+
})
60+
61+
$locationProvider.html5Mode(false).hashPrefix('');
62+
63+
msalProvider.init(
64+
// msal configuration
65+
);
66+
}]);
67+
}
68+
```
69+
70+
In Angular: app.module.ts
71+
72+
```javascript
73+
// Imports...
74+
@NgModule({
75+
declarations: [
76+
AppComponent,
77+
MsalComponent,
78+
MainMenuComponent,
79+
AccountMenuComponent,
80+
OsNavComponent
81+
],
82+
imports: [
83+
BrowserModule,
84+
AppRoutingModule,
85+
HttpClientModule,
86+
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }),
87+
MsalModule.forRoot(environment.MsalConfig),
88+
SuiModule,
89+
PagesModule
90+
],
91+
providers: [
92+
HttpServiceHelper,
93+
{provide: HTTP_INTERCEPTORS, useClass: MsalInterceptor, multi: true},
94+
AuthService
95+
],
96+
entryComponents: [
97+
AppComponent,
98+
MsalComponent
99+
]
100+
})
101+
export class AppModule {
102+
constructor() {
103+
console.log('APP Module Constructor!');
104+
}
105+
106+
ngDoBootstrap(ref: ApplicationRef) {
107+
if (window !== window.parent && !window.opener)
108+
{
109+
console.log("Bootstrap: MSAL");
110+
ref.bootstrap(MsalComponent);
111+
}
112+
else
113+
{
114+
//this.router.resetConfig(RouterModule);
115+
console.log("Bootstrap: App");
116+
ref.bootstrap(AppComponent);
117+
}
118+
}
119+
}
120+
```
121+
122+
MsalComponent:
123+
124+
```javascript
125+
import { Component} from '@angular/core';
126+
import { MsalService } from '@azure/msal-angular';
127+
128+
// This component is used only to avoid Angular reload
129+
// when doing acquireTokenSilent()
130+
131+
@Component({
132+
selector: 'app-root',
133+
template: '',
134+
})
135+
export class MsalComponent {
136+
constructor(private Msal: MsalService) {
137+
}
138+
}
139+
```
140+
141+
## Next steps
142+
Learn more about [building a single-page application (SPA)](scenario-spa-overview.md) using MSAL.js.
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
---
2+
title: Handle errors and exceptions in MSAL.js
3+
description: Learn how to handle errors and exceptions, Conditional Access claims challenges, and retries in MSAL.js applications.
4+
author: Dickson-Mwendia
5+
manager: CelesteDG
6+
ms.author: dmwendia
7+
ms.custom: devx-track-js
8+
ms.date: 11/26/2020
9+
ms.reviewer: saeeda, hahamil
10+
ms.service: active-directory
11+
ms.subservice: develop
12+
ms.topic: conceptual
13+
#Customer intent:
14+
---
15+
# Handle errors and exceptions in MSAL.js
16+
17+
[!INCLUDE [Active directory error handling introduction](./includes/error-handling-and-tips/error-handling-introduction.md)]
18+
19+
## Error handling in MSAL.js
20+
21+
MSAL.js provides error objects that abstract and classify the different types of common errors. It also provides an interface to access specific details of the errors such as error messages to handle them appropriately.
22+
23+
### Error object
24+
25+
```javascript
26+
export class AuthError extends Error {
27+
// This is a short code describing the error
28+
errorCode: string;
29+
// This is a descriptive string of the error,
30+
// and may also contain the mitigation strategy
31+
errorMessage: string;
32+
// Name of the error class
33+
this.name = "AuthError";
34+
}
35+
```
36+
37+
By extending the error class, you have access to the following properties:
38+
- `AuthError.message`: Same as the `errorMessage`.
39+
- `AuthError.stack`: Stack trace for thrown errors.
40+
41+
### Error types
42+
43+
The following error types are available:
44+
45+
- `AuthError`: Base error class for the MSAL.js library, also used for unexpected errors.
46+
47+
- `ClientAuthError`: Error class which denotes an issue with Client authentication. Most errors that come from the library are ClientAuthErrors. These errors result from things like calling a login method when login is already in progress, the user cancels the login, and so on.
48+
49+
- `ClientConfigurationError`: Error class, extends `ClientAuthError` thrown before requests are made when the given user config parameters are malformed or missing.
50+
51+
- `ServerError`: Error class, represents the error strings sent by the authentication server. These errors may be invalid request formats or parameters, or any other errors that prevent the server from authenticating or authorizing the user.
52+
53+
- `InteractionRequiredAuthError`: Error class, extends `ServerError` to represent server errors, which require an interactive call. This error is thrown by `acquireTokenSilent` if the user is required to interact with the server to provide credentials or consent for authentication/authorization. Error codes include `"interaction_required"`, `"login_required"`, and `"consent_required"`.
54+
55+
For error handling in authentication flows with redirect methods (`loginRedirect`, `acquireTokenRedirect`), you'll need to handle the redirect promise, which is called with success or failure after the redirect using the `handleRedirectPromise()` method as follows:
56+
57+
```javascript
58+
const msal = require('@azure/msal-browser');
59+
const myMSALObj = new msal.PublicClientApplication(msalConfig);
60+
61+
// Register Callbacks for redirect flow
62+
myMSALObj.handleRedirectPromise()
63+
.then(function (response) {
64+
//success response
65+
})
66+
.catch((error) => {
67+
console.log(error);
68+
})
69+
myMSALObj.acquireTokenRedirect(request);
70+
```
71+
72+
The methods for pop-up experience (`loginPopup`, `acquireTokenPopup`) return promises, so you can use the promise pattern (`.then` and `.catch`) to handle them as shown:
73+
74+
```javascript
75+
myMSALObj.acquireTokenPopup(request).then(
76+
function (response) {
77+
// success response
78+
}).catch(function (error) {
79+
console.log(error);
80+
});
81+
```
82+
83+
### Errors that require interaction
84+
85+
An error is returned when you attempt to use a non-interactive method of acquiring a token such as `acquireTokenSilent`, but MSAL couldn't do it silently.
86+
87+
Possible reasons are:
88+
89+
- you need to sign in
90+
- you need to consent
91+
- you need to go through a multi-factor authentication experience.
92+
93+
The remediation is to call an interactive method such as `acquireTokenPopup` or `acquireTokenRedirect`:
94+
95+
```javascript
96+
// Request for Access Token
97+
myMSALObj.acquireTokenSilent(request).then(function (response) {
98+
// call API
99+
}).catch( function (error) {
100+
// call acquireTokenPopup in case of acquireTokenSilent failure
101+
// due to interaction required
102+
if (error instanceof InteractionRequiredAuthError) {
103+
myMSALObj.acquireTokenPopup(request).then(
104+
function (response) {
105+
// call API
106+
}).catch(function (error) {
107+
console.log(error);
108+
});
109+
}
110+
});
111+
```
112+
113+
[!INCLUDE [Active directory error handling claims challenges](./includes/error-handling-and-tips/error-handling-claims-challenges.md)]
114+
115+
When getting tokens silently (using `acquireTokenSilent`) using MSAL.js, your application may receive errors when a [Conditional Access claims challenge](v2-conditional-access-dev-guide.md) such as MFA policy is required by an API you're trying to access.
116+
117+
The pattern to handle this error is to make an interactive call to acquire token in MSAL.js such as `acquireTokenPopup` or `acquireTokenRedirect` as in the following example:
118+
119+
```javascript
120+
myMSALObj.acquireTokenSilent(accessTokenRequest).then(function(accessTokenResponse) {
121+
// call API
122+
}).catch(function(error) {
123+
if (error instanceof InteractionRequiredAuthError) {
124+
125+
// extract, if exists, claims from the error object
126+
if (error.claims) {
127+
accessTokenRequest.claims = error.claims,
128+
129+
// call acquireTokenPopup in case of InteractionRequiredAuthError failure
130+
myMSALObj.acquireTokenPopup(accessTokenRequest).then(function(accessTokenResponse) {
131+
// call API
132+
}).catch(function(error) {
133+
console.log(error);
134+
});
135+
}
136+
});
137+
```
138+
139+
Interactively acquiring the token prompts the user and gives them the opportunity to satisfy the required Conditional Access policy.
140+
141+
When calling an API requiring Conditional Access, you can receive a claims challenge in the error from the API. In this case, you can pass the claims returned in the error to the `claims` parameter in the [access token request object](msal-js-pass-custom-state-authentication-request.md) to satisfy the appropriate policy.
142+
143+
See [How to use Continuous Access Evaluation enabled APIs in your applications](./app-resilience-continuous-access-evaluation.md) for more detail.
144+
145+
### Using other frameworks
146+
147+
Using toolkits like Tauri for registered single page applications (SPAs) with the identity platform are not recognized for production apps. SPAs only support URLs that start with `https` for production apps and `http://localhost` for local development. Prefixes like `tauri://localhost` cannot be used for browser apps. This format can only be supported for mobile or web apps as they have a confidential component unlike browser apps.
148+
149+
[!INCLUDE [Active directory error handling retries](./includes/error-handling-and-tips/error-handling-retries.md)]
150+
151+
## Next steps
152+
153+
Consider enabling [Logging in MSAL.js](msal-logging-js.md) to help you diagnose and debug issues
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
title: Logging errors and exceptions in MSAL.js
3+
description: Learn how to log errors and exceptions in MSAL.js
4+
author: Dickson-Mwendia
5+
manager: CelesteDG
6+
ms.author: dmwendia
7+
ms.custom: devx-track-js
8+
ms.date: 12/21/2021
9+
ms.reviewer: saeeda, jmprieur
10+
ms.service: active-directory
11+
ms.subservice: develop
12+
ms.topic: conceptual
13+
#Customer intent:
14+
---
15+
# Logging in MSAL.js
16+
17+
[!INCLUDE [MSAL logging introduction](./includes/error-handling-and-tips/error-logging-introduction.md)]
18+
19+
## Configure logging in MSAL.js
20+
21+
Enable logging in MSAL.js (JavaScript) by passing a loggerOptions object during the configuration for creating a `PublicClientApplication` instance. The only required config parameter is the client ID of the application. Everything else is optional, but may be required depending on your tenant and application model.
22+
23+
The loggerOptions object has the following properties:
24+
25+
- `loggerCallback`: a Callback function that can be provided by the developer to handle the logging of MSAL statements in a custom manner. Implement the `loggerCallback` function depending on how you want to redirect logs. The loggerCallback function has the following format ` (level: LogLevel, message: string, containsPii: boolean): void`
26+
- The supported log levels are: `Error`, `Warning`, `Info`, and `Verbose`. The default is `Info`.
27+
- `piiLoggingEnabled` (optional): if set to true, logs personal and organizational data. By default this is false so that your application doesn't log personal data. Personal data logs are never written to default outputs like Console, Logcat, or NSLog.
28+
29+
```javascript
30+
import msal from "@azure/msal-browser"
31+
32+
const msalConfig = {
33+
auth: {
34+
clientId: "enter_client_id_here",
35+
authority: "https://login.microsoftonline.com/common",
36+
knownAuthorities: [],
37+
cloudDiscoveryMetadata: "",
38+
redirectUri: "enter_redirect_uri_here",
39+
postLogoutRedirectUri: "enter_postlogout_uri_here",
40+
navigateToLoginRequestUrl: true,
41+
clientCapabilities: ["CP1"]
42+
},
43+
cache: {
44+
cacheLocation: "sessionStorage",
45+
storeAuthStateInCookie: false,
46+
secureCookies: false
47+
},
48+
system: {
49+
loggerOptions: {
50+
logLevel: msal.LogLevel.Verbose,
51+
loggerCallback: (level, message, containsPii) => {
52+
if (containsPii) {
53+
return;
54+
}
55+
switch (level) {
56+
case msal.LogLevel.Error:
57+
console.error(message);
58+
return;
59+
case msal.LogLevel.Info:
60+
console.info(message);
61+
return;
62+
case msal.LogLevel.Verbose:
63+
console.debug(message);
64+
return;
65+
case msal.LogLevel.Warning:
66+
console.warn(message);
67+
return;
68+
}
69+
},
70+
piiLoggingEnabled: false
71+
},
72+
},
73+
};
74+
```
75+
76+
## Next steps
77+
78+
For more code samples, refer to [Microsoft identity platform code samples](sample-v2-code.md).

0 commit comments

Comments
 (0)