We have two different unrelated AD organizations (tenants). And an AngularJS website which wants to login users via their AD account (OAuth, same as sign in with Facebook or Google flow), or register with some pre-filled information from their basic profile. We use adal.js library, without adal-angular.js.
Each tenant has its own single-tenant app created in the "App registration" section.
Problem
Both login and register works perfectly with the first tenant's app. User signs in at login.microsoftonline.com/{tenant-id}
(let's call it "MS page" for brevity), sees the "User Consent" page, accepts giving permission, MS page redirects back to our website with id_token in the url, our app sends request for access_token and receives it successfully.
But for the second tenant's app it receives AADSTS65001: #/error=interaction_required&error_description=AADSTS65001:+The+user+or+administrator+has+not+consented+to+use+the+application+with+ID+'ff1bb76e-7823-45a1-9950-b38fe8d3d0b4'.+Send+an+interactive+authorization+request+for+this+user+and+resource.&Trace+ID=...
when trying to get access_token after they signed in. But "User Consent" page is not shown, and there is no error message before this.
All interaction happens on the MS page, and it works differently in two different apps in two different AD organizations/tenants, which is a bit confusing.
Same things in both apps:
- our website code is the same in both cases (except for tenant id and client id ofc), it is deployed to the same url
- configuration of both apps is the same (cannot guarantee it, but we had a "shared screen" call, where we checked that manifest and all settings and permissions we know of have the same values)
- both apps were created from scratch in the new Azure portal, and we set only
oauth2AllowImplicitFlow: true
in manifest and Reply URLs, we did not change other settings - both apps have only one permission set in Required permissions: Windows Azure Active Directory - "Sign in and read user profile" delegated permission
Our adal config is the following:
var adAccessTokenResource: = 'https://graph.windows.net'
var adalOptions = {
tenant: tenantId,
clientId: clientId,
resource: adAccessTokenResource,
endpoints: { graphApiUri: adAccessTokenResource },
//popUp: true // does not work the same way for both true and false
}
Different things:
One possible difference is that we have our website at subdomain.{org-name}.com
where {org-name} is the same as the tenant-which-works name, so users have accounts username@{org-name}.com
there. Can this be the reason?
In addition, for some accounts of the second tenant, login.microsoftonline.com
redirects to the org-specific page to sign in the user. But for other accounts it does not, and error and behavior is the same in both cases.
After debugging with Fiddler we discovered that in both cases MS page sends the same POST https://login.microsoftonline.com/{tenant-id}/login
request. But for the working app it returns 200 response with the User Consent page. If user agrees - the second request POST /{tenant-id}/Consent/Grant
is sent, which returns 302 with id_token and redirects to our app, meaning that user has logged in. Our app asks for the access token on the redirect and this request works.
For the non-working app POST https://login.microsoftonline.com/{tenant-id}/login
returns 302 redirect with id_token right away, without showing the "User Consent" page. So, we get a redirect after the first request. Our app asks for the access token and gets an error that consent was not given.
Question
What can be possible cases for the differences in the behavior?
Or should only multi tenant app be used? We wanted to make it work with single tenant app at first.
I am new to Azure AD. Any help will be greatly appreciated.
As an update, we've eventually did it with some ugly hack, but with new msal library (also from Microsoft, is an official replacement for adal lib), our AD login code got much smaller and better, and we did not have the problem.
So, use msal.js library instead of obsolete adal.js one