AzureAD / azure-activedirectory-library-for-dotnet

ADAL authentication libraries for .net
http://aka.ms/aaddev
MIT License
358 stars 214 forks source link

AADSTS90002: Tenant authorize not found : Occurs after update pkg from 3.19.8 -> 4.0.0 #1346

Closed iomdesign closed 6 years ago

iomdesign commented 6 years ago

Which Version of ADAL are you using ? ADAL 4.0.0

Which platform has the issue?

What authentication flow has the issue?

Other? - please describe; Headless console app - client credentials flow

Repro

    public class OAuthConfiguration : IOAuthConfiguration
    {
        public string ClientId { get; set; }
        public string ClientSecret { get; set; }
        public string Authority { get; set; }
        public string Resource { get; set; }

    }

    public class OAuthProvider : IOAuthProvider
    {

        private readonly AuthenticationContext authContext;
        private AuthenticationResult authResult;
        private readonly OAuthConfiguration config;

...
        public OAuthProvider(
            OAuthConfiguration config,
            AuthenticationContext authContext
        )
        {
            this.authContext = authContext;
            this.config = config;
        }

        public async Task<AuthenticationResult> GetTokenAsync()
        {
            if (IsTokenExpired())
            {
                try
                {
                    var clientCredential = new ClientCredential(config.ClientId, config.ClientSecret);
                    this.authResult = await authContext.AcquireTokenAsync(config.Resource, clientCredential);

                }
                catch (Exception ex)
                {
                    logger.Error(
                        $"AUTH PROVIDER :: Failed to retrieve token :: {ex.message}");
                }
            }
            return this.authResult;
}

Expected behavior Using ADAL 3.19.8, the same code and credentials successfully returns an AuthenticaionResult containing a valid bearer token .

Actual behavior Exception thrown

AADSTS90002: Tenant authorize not found. This may happen if there are no active subscriptions for the tenant. Check with your subscription administrator. Trace ID: 9a1bb16e-0cdf-4dd4-8a4b-a888a2650e00 Correlation ID: 0aefb133-0763-426e-b0c3-4bb373b7a60d Timestamp: 2018-10-23 09:31:20Z

Possible Solution

Additional context/ Logs / Screenshots Add any other context about the problem here, such as logs and screebshots. Logging is described at https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/wiki/Logging-in-ADAL.Net

Another application using the same code and credentials but using ADAL 3.19.8 is still wrking as expected.

jmprieur commented 6 years ago

@iomdesign : how do you initialize the AuthContext? it seems that the authority is not recognized (See AADSTS90002)

can you please share the authority with us?

Also if you revert back to ADAL 3.19.8 does it still work?

TedPattison commented 6 years ago

I am getting the same error after migrating from 3.x to 4.3. It definitely seems like a breaking change when I have read that there should be no breaking changes when migrating from ADAL.NET 3 to 4. This does not seem to be the case.

Here is a little more info. I am authenticating using UserPasswordCredential. Yes, I know that auth with direct user password is frowned upon, but it is required due to the architecture of Power BI embedding. Here is the authorization endpoint I have been using to create the Authentication Context with ADAL.NET 3.x

When I used ADAL.NET 3.x with UserPasswordCredential, I can successfully acquire an access token and the call goes out to Azure AD using this URL.

https://login.windows.net/common/oauth2/authorize

After updating to ADAL.NET version 4.3, the library changes the URL to this and the call fails.

https://login.microsoftonline.com/authorize/oauth2/token

One other thing I noticed is that ADAL.NET 4.3 also adds a new form variable named client_info with a value of 1 which is passed when attempting to acquire an access token.

Can someone on the ADAL.NET team tell me whether this is a bug or this is expected behavior? If I need to use UserPasswordCredential to acquire an access token, should I avoid migrating to 4.3 and stay with 3.19.8?

jmprieur commented 6 years ago

Thanks for the repro @TedPattison. And sorry for the inconvenience. What you experience is not expected.

In order to narrow-down the issue, could you please try to set the authority to "https://login.microsoftonline.com/common" ? instead of "https://login.windows.net/common" when you initialize the application?

Also, given that you are using common, did you do as recommended: https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/wiki/AuthenticationContext-the-connection-to-Azure-AD#case-when-the-authority-is-not-known-in-advance ?

Jappinen commented 6 years ago

We ran into this as well. Switching authority url from https://login.microsoftonline.com/[guid]/oauth2/token to https://login.microsoftonline.com/[guid] fixed this.

It seems to new version somehow manages to mangle to POST target with the "long" url. From Fiddler:

v4.3.0: POST https://login.microsoftonline.com/authorize/oauth2/token HTTP/1.1

v3.19.8: POST https://login.microsoftonline.com/[guid]/oauth2/token HTTP/1.1

iomdesign commented 6 years ago

@jmprieur yes reverting to 3.19.8 fixes the issue.

The AuthContext is initialised via DI in a ServiceCollectionsExtension method.

        public static IServiceCollection AddODataClientFactory(this IServiceCollection services)
        {
            services
                .AddSingleton<IOAuthProvider, OAuthProvider>()
                .AddSingleton(provider =>
                    new AuthenticationContext(provider.GetRequiredService<IOptions<OAuthConfiguration>>().Value.Authority, false)
                )
                .AddSingleton(new ODataClientSettings())
                .AddScoped<IApiClient<ODataClient>, SimpleODataApiClient>()
                ;
            return services;
        }

The Authority is in the format https://login.microsoftonline.com/{Guid}/oauth2/authorize

TedPattison commented 6 years ago

Thanks Jean-Marc, This is what I first used to initialize AuthenticationContext

Both of these work in ADAL 3.19 but not in 4.3

Then after your suggestion I trimmed of the end of that URL and used this

This works fine now in 4.3. My problem is solved.

I guess when using UserPasswordCredential, the call goes to the token endpoint and not the authorization endpoint so it now makes sense why that changed is required. The other observation is that ADAL 3.19 is a more forgiving of a bad URL and while 4.3 is not. I am starting to read through the link you gave about using the common endpoint and how it relates to token caching. Great stuff.

Thanks again.

MarkZuber commented 6 years ago

For transparency...

https://login.microsoftonline.com/{Guid}/oauth2/authorize is not a valid authority. So what the code in 4.x is doing is looking at the tail end of the authority uri for what it expects to be the tenant (in this case, it should be {Guid} but only because the authority url should be https://login.microsoftonline.com/{Guid} [note without the oauth2/authorize which is an endpoint and not part of the authority]).

We are discussing internally how we want to resolve/catch this issue to make it clear (e.g. argumentexception if oauth2/authorize or other endpoint info is inside the authority uri) but 4.x is technically correct if sent a properly formatted authority. This explains why the changes folks have made are resolving the issue since it's now a properly formatted authority.

As for the other question on "client_info"=1 this is part of additional cache work to ensure we get the clientinfo structure back which contains information needed for full cache scenarios. It should not impact any of the behavior that you're seeing in this issue, but that's why the fiddler trace is different. This extra query parameter is expected.

jmprieur commented 6 years ago

Changing the tag to documentation and updated the release notes to make it very explicit that the authority, in the case of AAD should be: https://login.microsoftonline.com/{Guid} (where the Guid is the tenant ID or https://login.microsoftonline.com/domainName where the domain name is a domain associated with your tenant or https://login.microsoftonline.com/common which, in the case of ADAL.NET means any Azure AD tenant (note that the meaning is different in MSAL.NET)

I've updated the release notes: https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/wiki/Changes-adalnet-4.0#better-authority-validation

@iomdesign : I'm closing the issue as we believe the problem is solved (and your code need to be slightly fixed). But feel free to reopen if you disagree. Thanks you and to @TedPattison for clarifying!

jmprieur commented 6 years ago

reopening: we'll improve the exception in case the authority URL is ill-formed.

Alezis commented 6 years ago

Yep, the same for me. Switched on 4.3 and get broken token generation. I also use Power BI embedded. To get token we use master PRO account, i.e. UserPasswordCredential. Code was copied from this sample. Changing authorityURL fixed issues. ANother thing that my project targeted netcoreapp2.1, but obtaining token via user password and usage of UserPasswordCredential were removed, since I had to switch to net462. But power bi embedded use only this approach with master user to obtain embedded token. Frustrated.

jmprieur commented 6 years ago

Thanks @Alezis for pointing us to the source of the issues (the PowerBI sample which shows an incorrect authority). I'll work with the PowerBI team to have the sample changed. I also need to work with them to provide other auth flows ...

Thanks also for sharing your furstration. Is it an option for you to move to MSAL.NET? It has support for username/password in .NET Core (See https://aka.ms/msal-net-up) and the update from ADAL.NET to MSAL.NET is not that complicated (See https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/wiki/adalnet4-0-preview#do-you-want-to-migrate-from-adalnet-to-msalnet-). This is also the library where we are going to innovate moving forward.

iomdesign commented 6 years ago

Thanks @MarkZuber and @jmprieur, spot on!! Changing the resource config to https://login.microsoftonline.com/{TenantGuid} has it working :thumbsup: . Thanks for your assistance and a very useful library. Cheers.

AshleyAsh90 commented 5 years ago

Should the return(Result.Authority) from CreateFromResourceUrlAsync function also be modified to reflect this? Because I see that even in the ADAL 4.4.0 the authority returned is https://login.microsoftonline.com/{Guid}/oauth2/authorize -for Dynamics365

KaushalKhamar commented 5 years ago

Resolved by reverting the assembly "Microsoft.IdentityModel.Clients.ActiveDirectory" to Version=3.13.9.1126.

Using latest version of this assembly raised this issue. Version = 4.4.0.0

jmprieur commented 5 years ago

@KaushalKhamar . What do you use for the authority passed to the constructor ?

alohaninja commented 4 years ago

We also ran into this updating from ADAL v3 to v4 - followed this SO post recommendation and updated the authority from https://login.windows.net/<directoryId>/oauth2/authorize to https://login.microsoftonline.com/<directoryId> as this is a breaking change in ADAL v4