Skip to content
This repository has been archived by the owner on Jun 26, 2021. It is now read-only.
Navya Canumalla edited this page Dec 21, 2018 · 22 revisions

Q1. My app is re-loading every time adal renews a token.

Adal uses iframes to renew tokens silently in the background. AAD returns the token back to the redirect_uri specified in the token request (this redirect_uri must be registered with AAD). Since the response is a 302, it results in the html corresponding to the redirect_uri getting loaded in the iframe. Usually, it's the app's root/default page. This causes an app's reload. In other cases, if the app's root page requires authentication, it might lead to nested iframes or xframe deny error. Since, adal cannot cancel the 302 issued by AAD, it cannot prevent the redirect_uri from getting loaded in the iframe. But, there are workarounds for this that one can use to avoid the entire app reloading again or other errors caused because of this:

  • Specify a different html for the iframe:

    Set 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 AAD portal. This will not affect user's login experience as Adal saves the start page when user begins the login process and redirects back to the exact location after login is completed.

    Please look at the gist for an example of template html you can use. You will need to make some modifications to the html for it to work with your specific app: https://gist.github.com/tushargupta51/5fa6d000357120adbc8fd1d5c68853c4

  • Conditional initialization in your main app.js file: If your app is structured similar to our sample single-page app where there is one central Javascript file (app.js in the sample) that defines the app's initialization, routing and other stuff, you can use an if...else based on whether the app is loading in an iframe or not. Something like this: https://gist.github.com/tushargupta51/78ce0b6bce998f6851abd02d91eb3a95

Q2. My app gets into an infinite loop, sometimes leading to digest iterations error.

There could be multiple reasons for the infinite loop. I am detailing below the known causes:

  • If using ui-router: Most common cause of running into infinite loops when using ui-router is state transition error. The root causes are documented here #2238(summary version) and #600. One-line explanation of this is missing state definition for root page "/". Add this to your state provider routing:
     $stateProvider.state("/", {
            url: "/",
            templateUrl: <could be home page or default page",
            requireADLogin: true,
        });
  • Nested iframe creation: if an iframe is creating another iframe, this could lead to a loop where adal keeps sending token renewal requests. Please see this answer for more details.
  • Hash reset: Adal used to do reset the hash in the response sent from AAD in the locationChangeStart event. This sometimes was leading to multiple location change events and also app reload at times. This hash reset was removed in 1.0.11. Please use this version if none of the above solutions work for you.

Q3. Adal goes into infinite loop when renewing token and create nested iframes.

The root cause for this is same as Q1. Please try one of the solutions suggested in the answer.

Q4. I get this error "Refused to display ... in a frame because it set 'X-Frame-Options' to 'DENY'.

The root cause for this is same as Q1. Please try one of the solutions suggested in the answer.

Q5. How to use a Popup for Login/Authentication process?

Out-of-box support is provided in 1.0.12 and later versions of adal. Developers only need to set popUp: true on the config object.

For older versions:
Developers can use the displayCall method on the config object to define custom way of handling navigation during login process.

Explaining Code Snippet: The displayCall function opens a popup window and sets it's location to the login request url created by adal. It then sets up a timer that periodically checks if the pop up window URL contains the redirect URL, which will happen when login process is completed. When the above condition is true, it copies the hash of the popup window and move it to the hash of the main browser window. It then calls the Adal's handleWindowCallback method to extract the hash from the main window and close the pop up window. For all this to work, the redirect Uri of the application registered in Azure AD should match the redirectUri property of the config object. Below are the code snippets that you can add to the config object of your apps:

  • Code snippet for apps using plain Adal:
     window.config = {
        displayCall: function (urlNavigate) {
            var popupWindow = window.open(urlNavigate, "login", 'width=483, height=600');
            if (popupWindow && popupWindow.focus)
                popupWindow.focus();
            var registeredRedirectUri = this.redirectUri;
            var pollTimer = window.setInterval(function () {
                if (!popupWindow || popupWindow.closed || popupWindow.closed === undefined) {
                    window.clearInterval(pollTimer);
                }
                try {
                    if (popupWindow.document.URL.indexOf(registeredRedirectUri) != -1) {
                        window.clearInterval(pollTimer);
                        window.location.hash = popupWindow.location.hash;
                        authContext.handleWindowCallback();
                        popupWindow.close();
                    }
                } catch (e) {
                }
            }, 20);
        }
    };
  • Code snippet for apps using Adal-angular:
  adalProvider.init(
        {
          displayCall: function (urlNavigate) {
                var popupWindow = window.open(urlNavigate, "login", 'width=483, height=600');
                if (popupWindow && popupWindow.focus)
                    popupWindow.focus();
                var registeredRedirectUri = this.redirectUri;
                var pollTimer = window.setInterval(function () {
                    if (!popupWindow || popupWindow.closed || popupWindow.closed === undefined) {
                        window.clearInterval(pollTimer);
                    }
                    try {
                        if (popupWindow.document.URL.indexOf(registeredRedirectUri) != -1) {
                            window.clearInterval(pollTimer);
                            window.location.hash = popupWindow.location.hash;
                            popupWindow.close();
                        }
                    } catch (e) {
                    }
                }, 20);
            }
       },
        $httpProvider
        );

One thing to note is that the Redirect URL is set to the app's root page by default. This leads to the app being reloaded in the popup. The root cause for this is same as Q1. Please try one of the solutions suggested in the answer.

Q6. AADSTS50058: A silent sign-in request was sent but no user is signed in.

Error: 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).

Cause: This error occurs when adal sends a request to Azure AD to get a new access_token or id_token but there is no valid authentication cookie sent along with the request. As a result, AAD cannot identify the user and returns the above error. One of the following might be the reason for not sending the cookie:

  • Cookie Expired: If the authentication cookie, set up by Azure AD when user logged in, is expired or deleted. Usually, the cookie is valid until browsing session is valid which means closing the browser or leaving the browser idle for extended time can delete/expire the cookie.
    Solution: User needs to check the "Keep Me Signed In" checkbox if the authentication session should be persisted for longer period of time. Otherwise, application needs to log back the user in to create a new session.

  • Using IE/Edge: The token acquisition happens using iframes. IE/Edge have security zones that prevent sending cookies in an iframe if the iframe's and main app's domains are in different security zones. This means if your app's domain and AzureAD authority url are in different security zones, browser will not send the AAD cookie in the iframe request.
    Solution: Both app and Azure AD authority url need to be in the same security zone.

  • 3rd Party Cookies Blocked: If the 3rd party cookies are blocked by the browser, then cookies will not be sent along in the token request.
    Solution: User (or admin) needs to allow the 3rd party cookies for adal JS to work properly.

Q7. Token renewal operation failed due to timeout.

Starting in 1.0.12, Adal added timeout to acquireToken method. It waits for 6 seconds to receive response from AAD for a given acquire token request. If no response is sent within this time interval, adal sends the timeout error to the application. There are several reasons this might happen:

  1. Using Plain Js (non-angular): Ensure that adal.handleWindowCallback method is called when AAD sends the response to redirectUri. Whatever code is executed when the redirectUri page is loaded should ensure that handleWindowCallback method is called.

  2. Invalid RedirectUri: If redirectUri is not one of the registered redirectUris, then AAD will not send the response to the redirectUri, instead return html with error. Adal cannot process this html, hence return the timeout error since it did not receive any response in url fragements.

  3. LocationChangeHandler not getting called when using angular: Please ensure that locationChangeHandler in adal-angular.js must be called with the response from AAD. If that is not being called, then something is wrong. Providing logs and traces can help us find the issue.

Q8. Issues authenticating and acquiring tokens due to infinite redirect loops only on the Edge browser

Certain issues have been reported when using ADAL.js with the Microsoft Edge version 40.15063.0.0. Please take a look at this page of known issues for details and workarounds before filing a new issue.

Q9. How to handle interaction_required error due to conditional access policy

If your application is using ADAL.js to access a resource protected by a conditional access policy, it is possible you will run into the interaction_required error. Based on the need of your application, you can extract additional claims from the error and call acquireTokenPopup or acquireTokenRedirect to trigger another interactive authentication for the user to satisfy. Here are a few code samples for this case:

To learn more about these scenarios please read the conditional access article.

Q10. How to pass custom state parameter value in ADAL.js authentication request? For example: When you want to pass the page the user is or custom info to your redirect uri.

The state parameter as defined by OAuth2 is used for security to prevent cross-site request forgery attacks. It can also be used to encode information of the app's state before redirect. The Adal.js library uses the implicit grant flow which depends on the token being returned in the URL fragment in the browser. As a result, the query parameters cannot be added in the redirect URI and get trimmed off. The above recommendation to use state parameter for passing custom state applies to server side authentication flows since the state is preserved by the server. ADAL.js sets the state parameter in the browser storage such as localStorage and uses it to verify the response for security. You can similarly set and read your custom data as a separate parameter in the browser storage as well.

Having said that, the new MSAL.js library provides the feature in v0.2.1 to pass your custom state as part of the config options.

Clone this wiki locally