Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot acquireToken() with ios webview #3329

Closed
6 of 26 tasks
z33n00n opened this issue Mar 29, 2021 · 6 comments
Closed
6 of 26 tasks

Cannot acquireToken() with ios webview #3329

z33n00n opened this issue Mar 29, 2021 · 6 comments
Labels
msal-browser Related to msal-browser package question Customer is asking for a clarification, use case or information.

Comments

@z33n00n
Copy link

z33n00n commented Mar 29, 2021

Library

  • msal@1.x.x or @azure/msal@1.x.x
  • @azure/msal-browser@2.x.x
  • @azure/msal-node@1.x.x
  • @azure/msal-react@1.x.x
  • @azure/msal-angular@0.x.x
  • @azure/msal-angular@1.x.x
  • @azure/msal-angular@2.x.x
  • @azure/msal-angularjs@1.x.x

Framework

  • Angular
  • React
  • Other

Description

We are developing an Teams App and using msal-browser to authenticate our users. Everythings works fine on desktop, web and andoid, but with ios we are not able to get a token for the signed in user. SessionStorage doesn't contain any user information after signin.

Error Message

@ : Info - Emitting event: msal:ssoSilentStart
@azure/msal-browser@2.13.0 : Info - BrowserCacheManager.cleanRequestByState: Removing temporary cache items for state: eyJpZCI6IjA0Y2NkMjBjLTJlOTAtNDM5NC1iYTJjLThhYTYzMzRhZmM5MiIsIm1ldGEiOnsiaW50ZXJhY3Rpb25UeXBlIjoic2lsZW50In19
@ : Info - Emitting event: msal:ssoSilentFailure
Cannot login 'xxxx@xxxxx.onmicrosoft.com' using SSO!

{"name":"InteractionRequiredAuthError","message":"login_required: AADSTS50058: A silent sign-in request was sent but no user is signed in. The cookies used to represent the user's session were not sent in the request to Azure AD. This can happen if the user is using Internet Explorer or Edge, and the web app sending the silent sign-in request is in different IE security zone than the Azure AD endpoint (login.microsoftonline.com).\r\nTrace ID: 908ee49c-ea8a-4369-9e1b-788395205400\r\nCorrelation ID: bad0e556-7073-4112-b34f-abd11a5e5c73\r\nTimestamp: 2021-03-29 17:29:53Z","stack":"AuthError@..."}
@ : Info - Emitting event: msal:acquireTokenStart
@ : Info - Emitting event: msal:acquireTokenFromNetworkStart
@ : Info - Emitting event: msal:acquireTokenFailure
{"name":"ClientAuthError","message":"no_tokens_found: No tokens were found for the given scopes, and no authorization code was passed to acquireToken. You must retrieve an authorization code before making a call to acquireToken().","stack":"AuthError@...

sessionStorage
{"AI_sentBuffer":"[]","agentId":"8744a693-d709-40fb-85bc-f3f46e02a9d4","AI_buffer":"[]"}
localStorage
{}

MSAL Configuration

{
	auth: {
		clientId: this.clientId,
		authority: "https://login.microsoftonline.com/" + tid + "/",
		redirectUri: location.origin + "/Home/SignInEnd",
		navigateToLoginRequestUrl: false
	}, cache: {
		cacheLocation: BrowserCacheLocation.SessionStorage,
		storeAuthStateInCookie: true
	},system: {
		loggerOptions: {
			loggerCallback: (level: LogLevel, message: string, containsPii: boolean): void => {
				if (containsPii) {
					return;
				}
				switch (level) {
					case LogLevel.Error:
						console.error(message);
						return;
					case LogLevel.Info:
						console.info(message);
						return;
					case LogLevel.Verbose:
						console.log(message);
						return;
					case LogLevel.Warning:
						console.warn(message);
						return;
				}
			},
			piiLoggingEnabled: false
		}
	}
}

Reproduction steps

try aquireToken in a teams app with ios

Expected behavior

The same behavior like desktop, teams app or android: getting a token and store it to sessionStorage or anywhere else

Identity Provider

  • Azure AD
  • Azure B2C Basic Policy
  • Azure B2C Custom Policy
  • ADFS
  • Other

Browsers/Environment

  • Chrome
  • Firefox
  • Edge
  • Safari
  • IE
  • Other (iOS WebView 14.4.2)

Regression

  • Did this behavior work before?
    Version: iOS 13.3.x

Security

  • Is this issue security related?

Source

  • Internal (Microsoft)
  • Customer request
@z33n00n z33n00n added bug-unconfirmed A reported bug that needs to be investigated and confirmed question Customer is asking for a clarification, use case or information. labels Mar 29, 2021
@github-actions github-actions bot added msal-browser Related to msal-browser package more-information-needed Use this label when you are waiting on information from the issue creator and removed more-information-needed Use this label when you are waiting on information from the issue creator labels Mar 29, 2021
@sameerag
Copy link
Member

Is ITP enabled for iOS web view? I suspect it is safari which may be dropping cookies when an iframe is generated for ssoSilent(). cc @jasonnutter

@jasonnutter
Copy link
Contributor

jasonnutter commented Mar 30, 2021

Correct, this is likely caused by ITP, which is enabled in Safari Webviews by default now.

For Teams app SSO, it is recommended to use the on-behalf-of flow and/or interaction to achieve SSO if silent SSO does not work. Note, interaction in Teams apps must be done using the Teams JS SDK. This sample demonstrates both the OBO flow and performing interaction with MSAL.js and the Teams SDK: https://github.com/pnp/teams-dev-samples/tree/master/samples/tab-sso/src/nodejs

@jasonnutter jasonnutter removed the bug-unconfirmed A reported bug that needs to be investigated and confirmed label Mar 30, 2021
@z33n00n
Copy link
Author

z33n00n commented Mar 30, 2021

@jasonnutter Thanks for your response.
I looked at the example you provided and I think we do the same.
We don`t use the MsalProvider.

Our workflow, looks like this:

  1. Try to get an AccountInfo from the msal client (getAccountByUsername with the username from the teams context)
  2. If it is not successful, we try ssoSilent from the msal client with our scopes and the username
  3. If it is not successful, because the user never signed up, we start the authentication workflow with microsoftTeams.authentication.authenticate and loginRedirect() from the msal client which forwards to our popup-close function, which calls handleRedirectPromise() of the msal client (the sample uses addEventCallback here instead)
  4. This calls microsoftTeams.authentication.notifySuccess or microsoftTeams.authentication.notifyFailure
  5. If it is successful we try to get an AccountInfo from the msal client and this fails on the iOS device
  6. With the valid AccountInfo we try to get an token via acquireTokenSilent from msal client (we cannot use microsoftTeams.authentication.getAuthToken, because we need more rights to get data from graph

So, my questions:

  1. Is the way we are doing it right?
  2. Do we have to use MsalProvider?
  3. Should we use addEventCallback instead of handleRedirectPromise

Thanks for your help

@jasonnutter
Copy link
Contributor

jasonnutter commented Mar 31, 2021

If it is successful we try to get an AccountInfo from the msal client and this fails on the iOS device

How are you doing this part?

Do we have to use MsalProvider?

If you are using the MSAL React library, then yes, you do. But using MSAL React is optional.

@z33n00n
Copy link
Author

z33n00n commented Apr 1, 2021

How are you doing this part?

public async getAccount(userPrincipalName: string, scopes: string[]): Promise <AccountInfo> {
    let msalClient = this.MSALClient();

    if(!msalClient) {
        return null;
    }
    let account = msalClient.getAccountByUsername(userPrincipalName);

    if(account == null) {
        try {
            let SSORequest = {
                scopes: scopes,
                loginHint: userPrincipalName
            };
            const ssoResponse = await msalClient.ssoSilent(SSORequest);
            account = ssoResponse.account;
        } catch (error) {
            console.warn("Cannot login '" + userPrincipalName + "' using SSO!");
            console.warn(error);
        }
    }
    return account;
}

All other browsers and devices return an AccountInfo object from the cache after successful login by calling msalClient.getAccountByUsername. On iOS, there is nothing in the cache.

If you are using the MSAL React library, then yes, you do. But using MSAL React is optional.

Ok, we are not using MSAL React library currently.

Thanks for your help

@z33n00n
Copy link
Author

z33n00n commented Apr 1, 2021

@jasonnutter
The problem gave me no peace.
I have now tried something around and could solve the problem. SessionStorage is apparently not as persistent in iOS as it is in Android or Electron. Anyway, it was always empty between the calls.
I have now changed the cache location to localStorage and lo and behold, everything works. iOS is so developer unfriendly.

@z33n00n z33n00n closed this as completed Apr 1, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 9, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
msal-browser Related to msal-browser package question Customer is asking for a clarification, use case or information.
Projects
None yet
Development

No branches or pull requests

3 participants