Before you start here, make sure you understand how to initialize the application object.
The login APIs in MSAL retrieve an authorization code
which can be exchanged for an ID token for a signed in user, while consenting scopes for an additional resource, and an access token containing the user consented scopes to allow your app to securely call the API.
You can read more about ID tokens on our Azure Docs pages.
See here if you are uncertain about the differences between loginRedirect
and loginPopup
.
You must pass a request object to the login APIs. This object allows you to use different parameters in the request. See here for more information on the request object parameters.
For login requests, all parameters are optional, so you can just send an empty object.
- Popup
try {
const loginResponse = await msalInstance.loginPopup({});
} catch (err) {
// handle error
}
- Redirect
try {
msalInstance.loginRedirect({});
} catch (err) {
// handle error
}
Or you can send a set of scopes to pre-consent to:
- Popup
var loginRequest = {
scopes: ["user.read", "mail.send"], // optional Array<string>
};
try {
const loginResponse = await msalInstance.loginPopup(loginRequest);
} catch (err) {
// handle error
}
- Redirect
var loginRequest = {
scopes: ["user.read", "mail.send"], // optional Array<string>
};
try {
msalInstance.loginRedirect(loginRequest);
} catch (err) {
// handle error
}
When a login call has succeeded, you can use the getAllAccounts()
function to retrieve information about currently signed in users.
const myAccounts: AccountInfo[] = msalInstance.getAllAccounts();
If you know the account information, you can also retrieve the account information by using the getAccountByUsername()
or getAccountByHomeId()
APIs:
const username = "test@contoso.com";
const myAccount: AccountInfo = msalInstance.getAccountByUsername(username);
const homeAccountId = "userid.hometenantid"; // Best to retrieve the homeAccountId from an account object previously obtained through msal
const myAccount: AccountInfo = msalInstance.getAccountByHomeId(homeAccountId);
Note: getAccountByUsername()
is provided for convenience and should be considered less reliable than getAccountByHomeId()
. When possible use getAccountByHomeId()
.
In B2C scenarios your B2C tenant will need to be configured to return the emails
claim on idTokens
in order to use the getAccountByUsername()
API.
These APIs will return an account object or an array of account objects with the following signature:
{
// home account identifier for this account object
homeAccountId: string;
// Entity who issued the token represented as a full host of it (e.g. login.microsoftonline.com)
environment: string;
// Full tenant or organizational id that this account belongs to
tenantId: string;
// preferred_username claim of the id_token that represents this account.
username: string;
}
If you already have a session that exists with the authentication server, you can use the ssoSilent() API to make requests for tokens without interaction.
If you already have the user's sign-in information, you can pass this into the API to improve performance and ensure that the authorization server will look for the correct account session. You can pass one of the following into the request object in order to successfully obtain a token silently.
It is recommended to leverage the login_hint
optional ID token claim (provided to ssoSilent
as loginHint
), as it is the most reliable account hint of silent (and interactive) requests.
account
(which can be retrieved using on of the account APIs)sid
(which can be retrieved from theidTokenClaims
of anaccount
object)login_hint
(which can be retrieved from either the account objectlogin_hint
ID token claim,username
property, or theupn
ID token claim)
Passing an account will look for the login_hint
optional ID token claim (preferred), then the sid
optional id token claim, then fall back to loginHint
(if provided) or account username.
const silentRequest = {
scopes: ["User.Read", "Mail.Read"],
loginHint: "user@contoso.com",
};
try {
const loginResponse = await msalInstance.ssoSilent(silentRequest);
} catch (err) {
if (err instanceof InteractionRequiredAuthError) {
const loginResponse = await msalInstance
.loginPopup(silentRequest)
.catch((error) => {
// handle error
});
} else {
// handle error
}
}
If there is not enough information available about the user, you can attempt to use the ssoSilent
API without passing an account
, sid
or login_hint
.
const silentRequest = {
scopes: ["User.Read", "Mail.Read"],
};
However, be aware that if your application has code paths for multiple users in a single browser session, or if the user has multiple accounts for that single browser session, then there is a higher likelihood of silent sign-in errors. You may see the following error show up in the event of multiple account sessions found by the authorization server:
InteractionRequiredAuthError: interaction_required: AADSTS16000: Either multiple user identities are available for the current request or selected account is not supported for the scenario.
This indicates that the server could not determine which account to sign into, and will require either one of the parameters above (account
, login_hint
, sid
) or an interactive sign-in to choose the account.
Warning
When using ssoSilent
, the service will attempt to load your redirect URI page in an invisible embedded iframe. Content security policies and HTTP header values present in your app's redirect URI page response, such as X-FRAME-OPTIONS: DENY
and X-FRAME-OPTIONS: SAMEORIGIN
, can prevent your app from loading in said iframe, effectively blocking silent SSO. If you intend you use ssoSilent
, please make sure the redirect URI points to a page that does not implement any such policies.
When using popup and silent APIs we recommend setting the redirectUri
to a blank page or a page that does not implement MSAL. This will help prevent potential issues as well as improve performance. If your application is only using popup and silent APIs you can set this on the PublicClientApplication
config. If your application also needs to support redirect APIs you can set the redirectUri
on a per request basis. For more information, see the React Router sample:
Note: This does not apply for loginRedirect
or acquireTokenRedirect
. When using those APIs please see the directions on handling redirects here
msalInstance.loginPopup({
redirectUri: "http://localhost:3000/blank.html",
});
Learn how to acquire and use an access token!