none
WebApp JS SDK API access denied AADSTS650052 RRS feed

  • Question

  • Hello,

    We have a single page app that uses the JS SDK to build graphics from data stored in TSI.

    The web app is registered in the App Registration in the Azure AD. The configuration is according to the documentation:

    • In the manifest - "oauth2AllowImplicitFlow" was set to true
    • Azure Time Series Insights was added to the "Required permissions"
    • App registration is set to multi tenant
    • The app registration was added to the TSI "Data Access Policies"
    • Users were added to the TSI "Data Access Policies"

    When using the site with a user from the same tenant as the owner of the resources everything works fine. 

    We started to add users and everyone with hotmail or gmail accounts were also able to access the data.

    However people who have a company domain in their emails were not able to access. After login in an error message appeared:

    "access_denied AADSTS650052: The app needs access to a service (\"https://api.timeseries.azure.com/\") that your organization XXXXX has not subscribed or enabled. Contact your IT admin to review configuration of your service subscriptions"

    This has to be an error in the configuration because when these people use the https://insights.timeseries.azure.com/preview site they are able to view the data just fine.

    The following code is used for Adal and TSI Auth

    //
    //ADAL
    //
    function authenticate()
    {
    	if(authenticationContext.isCallback(window.location.hash))
    	{
    		authenticationContext.handleWindowCallback();
    		
    		var error = authenticationContext.getLoginError();
    		if(error)
    		{
    			adal_authenticated = false;
    			
    			
    			// TODO: Handle errors signing in and getting tokens
    			document.getElementById('api_response').textContent = error;
    			document.getElementById('loginModal').style.display = "block";
    		}
    		else
    		{
    			adal_authenticated = true;
    		}
    	}
    	else
    	{
    		var user = authenticationContext.getCachedUser();
    		if(user)
    		{
    			adal_authenticated = true;
    			
    			document.getElementById('username').textContent = user.userName;
    		}
    		else
    		{
    			adal_authenticated = false;
    			
    			document.getElementById('username').textContent = 'Not signed in.';
    			
    			logUserIn();
    		}
    	}
    }
    
    function authenticationContextCallbackFunction(errorDesc, token, error, tokenType)
    {
    	if(error)
    	{
    		adal_authenticated = false;
    		
    		alert(error + " " + errorDesc);
    	}
    }
    
    function logUserIn()
    {
    	var user = authenticationContext.getCachedUser();
    	if(user)
    	{
    		getAccessToken();
    	}
    	else
    	{
    		authenticationContext.login();
    	}
    }
    
    function getAccessToken()
    {
    	authenticationContext.acquireToken(
    		'https://api.timeseries.azure.com/',
    		function(errorDesc, token, error)
    		{
    			if(error)
    			{
    				adal_authenticated = false;
    			
    				alert(error + " " + errorDesc);
    			}
    			else
    			{
    				adal_authenticated = true;
    			}
    		});
    }
    
    //
    //TSI authentication
    //
    authenticationContext.getTsiToken = function()
    {
    	document.getElementById('api_response2').textContent = 'Getting tsi token...';
    	
    	//Get an access token to the Microsoft TSI API
    	var promise = new Promise(function(resolve, reject)
    	{
    		authenticationContext.acquireToken(
    			'https://api.timeseries.azure.com/',
    			function(error, token)
    			{
    				if(error || !token)
    				{
    					// TODO: Handle error obtaining access token
    					document.getElementById('api_response').textContent = error;
    					document.getElementById('loginModal').style.display = "block";
    					document.getElementById('api_response2').textContent = '';
    					return;
    				}
    				else
    				{
    					// Use the access token
    					document.getElementById('api_response').textContent = '';
    					document.getElementById('api_response2').textContent = '';
    					document.getElementById('loginModal').style.display = "none";
    					resolve(token);
    				}
    			}
    		);
    	});
    	
    	return promise;
    }
    
    The header has the following properties
    const azureEnvironment = "myenviromentXXXXXX.env.timeseries.azure.com";
    
    var authenticationContext = new AuthenticationContext(
    {
    	clientId: 'Id of the app registration in Azure AD XXXXXX',
    	postLogoutRedirectUri: 'my website adress XXXXXXX',
    	redirectUri: 'my website adress XXXXXXX',
    	
    	callback: authenticationContextCallbackFunction
    });

    Thursday, February 21, 2019 8:22 PM

Answers

  • The issue was with specifying the tenant.

    Since the tenant defaults to common if none is specified, whenever someone authenticated from a company that had a onmicrosoft service, the auth would assume their tenant and give an error because they did not have a TSI service.

    Specifying the tenat in the header solved the issue.

    • Marked as answer by dtwaydd Saturday, March 30, 2019 9:40 AM
    Saturday, March 30, 2019 9:40 AM

All replies

  • Hi, I think this question would gain more traction with the community in the Azure Active Directory forum. Can you please share more about your scenario? Are these guest users that belong to a different company than yours? How did you added the users? Is there a guide you were following on how to add the users?
    Saturday, February 23, 2019 1:38 AM
    Moderator
  • Hello,

    Indeed the users belong to a different company and are registered as guests.

    They were added in the Data Access Policies under the TSI instance that is being used.

    I was following this article:

    Tutorial: Create an Azure Time Series Insights single-page web app

    But there was nothing in it about multi tenant, so I kind of went along trying different options and reading up on multi-tenant web apps from the azure documentation.


    Saturday, February 23, 2019 2:56 PM
  • The issue was with specifying the tenant.

    Since the tenant defaults to common if none is specified, whenever someone authenticated from a company that had a onmicrosoft service, the auth would assume their tenant and give an error because they did not have a TSI service.

    Specifying the tenat in the header solved the issue.

    • Marked as answer by dtwaydd Saturday, March 30, 2019 9:40 AM
    Saturday, March 30, 2019 9:40 AM
  • Glad to hear that your issue is resolved. Appreciate for sharing the resolution, this would certainly benefit other community members.

    Monday, April 1, 2019 8:34 AM
    Moderator
  • Any chance you could give more insight into how you fixed this?  I have a very similar issue where I have a multitenant angular app with a .NET backend API, and I swear I've set up everything properly in the app registrations in Azure but am getting this same error where users from other directories try to log in and use the backend API.

    Everything is set up to be authorized through the common endpoint.  Are you saying in your solution that I should not be doing that?

    Thanks!

     
    Saturday, June 22, 2019 9:00 PM
  • Hello,

    Sorry for the delayed response.

    I am not an expert in this subject, so take my experience with a grain of salt.

    If a guest user, that has a domain that is registered in another azure tenant, authenticates in a common endpoint, it's as if he is login in to his company services. 

    In that case you need to specify which tenant you want him login in to, so it doesn't default to his company's one.

    So if you specify your tenant in the header, the guest user will be login in to your services and that should solve the issue.

    Monday, July 8, 2019 8:07 AM