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

[Bug] Cannot use personal account to login to KeyVault #1932

Closed
1 of 7 tasks
Crossbow78 opened this issue Jul 13, 2020 · 13 comments
Closed
1 of 7 tasks

[Bug] Cannot use personal account to login to KeyVault #1932

Crossbow78 opened this issue Jul 13, 2020 · 13 comments

Comments

@Crossbow78
Copy link

Crossbow78 commented Jul 13, 2020

Which Version of MSAL are you using ?

  • Microsoft.Identity.Client 4.16.1
  • Microsoft.Azure.KeyVault 3.0.5

Platform
.NET Core 3.1

What authentication flow has the issue?

  • Desktop / Mobile
    • Interactive
    • Integrated Windows Auth
    • Username Password
    • Device code flow (browserless)
  • Web App
    • Authorization code
    • OBO
  • Web API
    • OBO

Is this a new or existing app?
This is a new app or experiment. Trying to retrieve a key vault certificate via a proof-of-concept console application. User needs to authenticate, access policies are granted to user principals.

Repro

  • Create app registration

  • Make sure that there is a personal Microsoft account as a guest or member in the tenant.

  • To this account grant access to a Key Vault (via group or user), and grant certificate list/read permission.

  • Use minimal code example as below

    public class CertificateRetriever
    {
        private KeyVaultClient _client = new KeyVaultClient(AcquireMSALToken);
        private string _clientId;

        public CertificateRetriever(string clientId)
        {
            _clientId = clientId;
        }

        public async Task<IList<CertificateItem>> GetCertificatesFromKeyVault(string vaultUri)
        {
            var certificates = await _client.GetCertificatesAsync(vaultUri);
            return certificates.ToList();
        }

        private async Task<string> AcquireMSALToken(string authority, string resource, string scope)
        {
            var app = PublicClientApplicationBuilder
                .Create(_clientId)
                .WithDefaultRedirectUri()
                .WithAuthority(AadAuthorityAudience.AzureAdAndPersonalMicrosoftAccount)
                .Build();

            var scopes = new[] { "https://vault.azure.net/.default" };  // Must override scope...?
            var authResult = await app.AcquireTokenInteractive(scopes).ExecuteAsync();
            return authResult.AccessToken;
        }
    }

    class Program
    {
        static async Task Main(string[] args)
        {
            var retriever = new CertificateRetriever("xxxxxxxx-xxxx-xxxx-xxxx-46891353d034");  // App registration
            var certificates = await retriever.GetCertificatesFromKeyVault("https://xxxxxxxxxx.vault.azure.net/");
        }
    }

Expected behavior

  • User is prompted to login, and can use a personal Microsoft account
  • Certificates are retrieved successfully

Actual behavior

  • Unable to select Microsoft account, if the above scope ("https://vault.azure.net/.default") is specified
  • The authorization callback is called with an empty string as scope argument. If this empty scope is used, the user can use a personal Microsoft account (and will receive a token), but will then get 'Unauthorized' on Key Vault access.

Additional context/ Logs / Screenshots
My main question is:

  • Why is the scope argument empty upon logging on to the key vault?
  • What determines the restriction for directory accounts only?
@bgavrilMS bgavrilMS added this to To do in Ongoing Support and OPS via automation Jul 13, 2020
@bgavrilMS
Copy link
Member

Hi @Crossbow78 - please try to use use:

image

@Crossbow78
Copy link
Author

I have exactly that same API permission defined in my app registration.

And I've replaced the scope override in code with:

var scopes = new[] { "https://vault.azure.net/user_impersonation" };  // Must override scope...?

But it gives me exactly the same result, only allowing me to select Azure tenant accounts.
Note that I've already tried enabling verbose logging on the PublicClientApplication, but that didn't mention anything about the allowed audience.

Are you able to reproduce? What else could I try?

@bgavrilMS
Copy link
Member

bgavrilMS commented Jul 13, 2020

This is not an MSAL issue, as MSAL does not control the dialog between the user and the Identity Provider. MSAL only pops up the browser and caches the tokens. I'm getting the same error as you by the way, so I don't think it's a configuration issue on the App Registration.

It's quite possible that KeyVault does not allow MSA logins.

image

@bgavrilMS bgavrilMS self-assigned this Jul 13, 2020
@bgavrilMS bgavrilMS moved this from To do to In progress in Ongoing Support and OPS Jul 13, 2020
@bgavrilMS bgavrilMS changed the title [Bug] Cannot use personal account when using MSAL [Bug] Cannot use personal account to login to KeyVault Jul 13, 2020
@Crossbow78
Copy link
Author

Crossbow78 commented Jul 13, 2020

Note that I can use the ADAL (*) library for authentication and it will work fine with a personal account and I receive my certificates, but the interactive flow is a lot less practical (I'm just copying url's from and to a console window to get past)...
This led me to believe MSAL is somehow involved in the 'negotiation' about the effective sign-in audience...

Also, I still don't understand why I have to override the empty scope parameter that gets passed in to the MSAL token provider callback. Why is it empty? That will never work when accessing multiple resources, right?

(*) Microsoft.IdentityModel.Clients.ActiveDirectory 5.2.8

@bgavrilMS
Copy link
Member

I'm not sure what you mean by using ADAL, as ADAL targets the v1 endpoint of AAD, which does not support personal accounts. The flow where the user gets an url and a code in the console and they pick it up is called DeviceCodeFlow, and it is supported by both ADAL and MSAL.

I don't know why the KeyVault SDK doesn't advertise a scope, I assume it is because they are still focused on integratin with ADAL. We are hopeful that this will change soon and some of our PMs are reaching out (CC @aiwangmicrosoft ), as ADAL is deprecated.

I think it is reasonable to open issues on the KeyVault SDK or service to see why this limitation exists.

@jmprieur - would you know why KeyVault does not allow MSA auth?

@bgavrilMS bgavrilMS moved this from In progress to Done in Ongoing Support and OPS Jul 31, 2020
@jmprieur
Copy link
Contributor

jmprieur commented Oct 15, 2020

@Crossbow78 : do you use the same clientID in your ADAL and MSAL application? (would you have reused a well known clientID for your ADAL application?, which you don't use in the MSAL application)?

What you should do is use a tenanted authority, rather than common.
I suspect that your MSA is a guest of your tenant, and guest scenarios only work with tenanted authorities.

@matthew25187
Copy link

I seem to have encountered a similar problem. Using essentially the same code as in the original post (for the public client application), when attempting to login with my MSA I get the following error on entering the user name (e-mail address):
image
I don't get an opportunity to enter the password and have to cancel the login attempt. Trying a different MSA also resulted in the same problem. The relevant portion of the log output:
Info: (False) MSAL 4.21.1.0 MSAL.UAP N/A [10/26/2020 00:18:40 - 286091f6-871c-4cff-9993-19a0374ffd62] MSAL MSAL.UAP with assembly version '4.21.1.0'. CorrelationId(286091f6-871c-4cff-9993-19a0374ffd62)
Info: (False) MSAL 4.21.1.0 MSAL.UAP N/A [10/26/2020 00:18:40 - 286091f6-871c-4cff-9993-19a0374ffd62] === InteractiveParameters Data ===
LoginHint provided: False
User provided: False
UseEmbeddedWebView: NotSpecified
ExtraScopesToConsent:
Prompt: not_specified
HasCustomWebUi: False

Info: (False) MSAL 4.21.1.0 MSAL.UAP N/A [10/26/2020 00:18:40 - 286091f6-871c-4cff-9993-19a0374ffd62]
=== Request Data ===
Authority Provided? - True
Scopes - https://vault.azure.net/.default
Extra Query Params Keys (space separated) -
ApiId - AcquireTokenInteractive
IsConfidentialClient - False
SendX5C - False
LoginHint ? False
IsBrokerConfigured - False
HomeAccountId - False
CorrelationId - 286091f6-871c-4cff-9993-19a0374ffd62

Info: (False) MSAL 4.21.1.0 MSAL.UAP N/A [10/26/2020 00:18:40 - 286091f6-871c-4cff-9993-19a0374ffd62] === Token Acquisition (InteractiveRequest) started:

Authority Host: login.microsoftonline.com

Verbose: (False) MSAL 4.21.1.0 MSAL.UAP N/A [10/26/2020 00:18:40 - 286091f6-871c-4cff-9993-19a0374ffd62] [Instance Discovery] Tried to use network cache provider for login.microsoftonline.com. Success? False
Info: (False) MSAL 4.21.1.0 MSAL.UAP N/A [10/26/2020 00:18:40 - 286091f6-871c-4cff-9993-19a0374ffd62] Fetching instance discovery from the network from host login.microsoftonline.com
onecoreuap\windows\wgi\winrt\display\displaycommon.cpp(411)\Windows.Graphics.dll!50D8185B: (caller: 50D7E797) ReturnHr(4) tid(5818) 80070490 Element not found.
onecoreuap\windows\wgi\winrt\display\displaycommon.cpp(411)\Windows.Graphics.dll!50D8185B: (caller: 50D85FD1) ReturnHr(5) tid(5818) 80070490 Element not found.
The thread 0x4a34 has exited with code 0 (0x0).
Verbose: (False) MSAL 4.21.1.0 MSAL.UAP N/A [10/26/2020 00:18:41 - 286091f6-871c-4cff-9993-19a0374ffd62] [Instance Discovery] Tried to use network cache provider for login.microsoftonline.com. Success? True
Verbose: (False) MSAL 4.21.1.0 MSAL.UAP N/A [10/26/2020 00:18:41 - 286091f6-871c-4cff-9993-19a0374ffd62] [Instance Discovery] After hitting the discovery endpoint, the network provider found an entry for login.microsoftonline.com ? True
Info: (False) MSAL 4.21.1.0 MSAL.UAP N/A [10/26/2020 00:18:41 - 286091f6-871c-4cff-9993-19a0374ffd62] Resolving authority endpoints... Already resolved? - FALSE
onecore\com\combase\dcomrem\marshal.cxx(1111)\combase.dll!76DC5228: (caller: 76D2E81C) ReturnHr(1) tid(5818) 80004002 No such interface supported
Msg:[Failed to marshal with IID={11D3B13A-180E-4789-A8BE-7712882893E6}]
onecore\com\combase\dcomrem\marshal.cxx(1032)\combase.dll!76D2E978: (caller: 76D46523) LogHr(1) tid(5818) 80004002 No such interface supported
onecore\com\combase\dcomrem\marshal.cxx(972)\combase.dll!76D46579: (caller: 6E7D4EBF) ReturnHr(2) tid(5818) 80004002 No such interface supported
The thread 0x5f1c has exited with code 0 (0x0).
The thread 0x6af8 has exited with code 0 (0x0).
The thread 0x48b0 has exited with code 0 (0x0).
Info: (False) MSAL 4.21.1.0 MSAL.UAP N/A [10/26/2020 00:18:55 - 286091f6-871c-4cff-9993-19a0374ffd62] Authorization result status returned user cancelled authentication.
Error: (False) MSAL 4.21.1.0 MSAL.UAP N/A [10/26/2020 00:18:55 - 286091f6-871c-4cff-9993-19a0374ffd62] Exception type: Microsoft.Identity.Client.MsalClientException
, ErrorCode: authentication_canceled

at Microsoft.Identity.Client.Internal.AuthCodeRequestComponent.VerifyAuthorizationResult(AuthorizationResult authorizationResult, String originalState)
at Microsoft.Identity.Client.Internal.AuthCodeRequestComponent.d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.Internal.AuthCodeRequestComponent.d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.Internal.Requests.InteractiveRequest.d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.Internal.Requests.InteractiveRequest.d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.d__14.MoveNext()
Exception thrown: 'Microsoft.Identity.Client.MsalClientException' in System.Private.CoreLib.ni.dll
Exception thrown: 'Microsoft.Identity.Client.MsalClientException' in System.Private.CoreLib.ni.dll
Exception thrown: 'Microsoft.Identity.Client.MsalClientException' in System.Private.CoreLib.ni.dll
Exception thrown: 'Microsoft.Identity.Client.MsalClientException' in System.Private.CoreLib.ni.dll
Exception thrown: 'Microsoft.Identity.Client.MsalClientException' in System.Private.CoreLib.ni.dll
An exception of type 'Microsoft.Identity.Client.MsalClientException' occurred in System.Private.CoreLib.ni.dll but was not handled in user code
User canceled authentication.

I was previously trying to use Azure AD authentication (REST API, OAuth2 1.0) but decided to try MSAL after having other issues with that approach. At least when using AAD I was on all occasions able to enter my MSA's ID and password before any problems occurred, unlike with MSAL where I've never got as far as being able to enter the password (same MSA). With the same AD and app configuration at the Azure end, why would I be getting this username error only when switching over to using MSAL?

@jmprieur
Copy link
Contributor

jmprieur commented Oct 26, 2020

What is the sign-in audience of your application @Crossbow78
Did you specify a tenanted authority when that worked, but "common" or "organization" when this does not work with an MSA?

when you use an authority with a tenant, this enables guest accounts to sign-in, and your MSA might be a guest account of the tenant, which would work. When using "common" or "organization", the guest scenario does no longer apply, and your MSA is considered as an MSA, which I don't think is supported by KeyVault yet (Azure Resource Management does not yet support MSA)

@Crossbow78
Copy link
Author

Crossbow78 commented Oct 27, 2020

I'm trying to understand what you're asking... what is a "tenanted authority"? And what's "common" referring to?

My sign-in audience in the app registration manifest is "AzureADandPersonalMicrosoftAccount" (as mentioned in the original post). When using the interactive browser authentication flow, it brings up the Microsoft Account prompt, but it will not allow me to even attempt to login with a personal Microsoft account:
image

Trying to acquire token
   Authority: https://login.windows.net/xxxxxxxx-xxxx-xxxx-xxxx-23216c2f12e4
   Resource: https://vault.azure.net
   Scope:
(False) MSAL 4.16.1.0 MSAL.NetCore Microsoft Windows 10.0.18363 [10/27/2020 00:37:24 - 739db67b-ec4b-44d7-8180-5d90aa9c1bcc] MSAL MSAL.NetCore with assembly version '4.16.1.0'. CorrelationId(739db67b-ec4b-44d7-8180-5d90aa9c1bcc)
(False) MSAL 4.16.1.0 MSAL.NetCore Microsoft Windows 10.0.18363 [10/27/2020 00:37:24 - 739db67b-ec4b-44d7-8180-5d90aa9c1bcc] === InteractiveParameters Data ===
LoginHint provided: False
User provided: False
UseEmbeddedWebView: NotSpecified
ExtraScopesToConsent:
Prompt: select_account
HasCustomWebUi: False

(True) MSAL 4.16.1.0 MSAL.NetCore Microsoft Windows 10.0.18363 [10/27/2020 00:37:25 - 739db67b-ec4b-44d7-8180-5d90aa9c1bcc]
=== Request Data ===
Authority Provided? - True
Client Id - xxxxxxxx-xxxx-xxxx-xxxx-46891353d034
Scopes - https://vault.azure.net/.default
Redirect Uri - http://localhost
Extra Query Params Keys (space separated) -
ClaimsAndClientCapabilities -
Authority - https://login.microsoftonline.com/common/
ApiId - AcquireTokenInteractive
IsConfidentialClient - False
SendX5C - False
LoginHint -
IsBrokerConfigured - False
HomeAccountId -

(True) MSAL 4.16.1.0 MSAL.NetCore Microsoft Windows 10.0.18363 [10/27/2020 00:37:25 - 739db67b-ec4b-44d7-8180-5d90aa9c1bcc] === Token Acquisition (InteractiveRequest) started:
        Authority: https://login.microsoftonline.com/common/
        Scope: https://vault.azure.net/.default
        ClientId: xxxxxxx-xxxx-xxxx-xxxx-46891353d034

(False) MSAL 4.16.1.0 MSAL.NetCore Microsoft Windows 10.0.18363 [10/27/2020 00:37:25 - 739db67b-ec4b-44d7-8180-5d90aa9c1bcc] [Instance Discovery] Tried to use network cache provider for login.microsoftonline.com. Success? False
(True) MSAL 4.16.1.0 MSAL.NetCore Microsoft Windows 10.0.18363 [10/27/2020 00:37:25 - 739db67b-ec4b-44d7-8180-5d90aa9c1bcc] Fetching instance discovery from the network from host login.microsoftonline.com. Endpoint https://login.microsoftonline.com/common/discovery/instance
(False) MSAL 4.16.1.0 MSAL.NetCore Microsoft Windows 10.0.18363 [10/27/2020 00:37:25 - 739db67b-ec4b-44d7-8180-5d90aa9c1bcc] [Instance Discovery] Tried to use network cache provider for login.microsoftonline.com. Success? True
(False) MSAL 4.16.1.0 MSAL.NetCore Microsoft Windows 10.0.18363 [10/27/2020 00:37:25 - 739db67b-ec4b-44d7-8180-5d90aa9c1bcc] [Instance Discovery] After hitting the discovery endpoint, the network provider found an entry for login.microsoftonline.com ? True
(False) MSAL 4.16.1.0 MSAL.NetCore Microsoft Windows 10.0.18363 [10/27/2020 00:37:25 - 739db67b-ec4b-44d7-8180-5d90aa9c1bcc] Resolving authority endpoints... Already resolved? - FALSE
(False) MSAL 4.16.1.0 MSAL.NetCore Microsoft Windows 10.0.18363 [10/27/2020 00:37:25 - 739db67b-ec4b-44d7-8180-5d90aa9c1bcc] Listening for authorization code on http://localhost:63491/

Edit:
I just tried the code from my opening post, but changed:

                .WithAuthority(AadAuthorityAudience.AzureAdAndPersonalMicrosoftAccount)

into:

                .WithAuthority(AadAuthorityAudience.AzureAdMyOrg)
                .WithTenantId("xxxxxxxx-xxxx-xxxx-xxxx-23216c2f12e4")

And that results in a prompt where I can select from my personal accounts and the certificate is successfully retrieved (using an account that is invited as a guest in this tenant and also in my key vault access policies).

@jmprieur
Copy link
Contributor

Sorry, I should have been clearer. Yes; the authority you need to use needs to have a tenant (tenanted)

@jmprieur
Copy link
Contributor

Closing as the question is answered

@Crossbow78
Copy link
Author

The relevance of the app registration's sign-in audience setting of AzureADandPersonalMicrosoftAccount and the authority 'override' to AzureAdMyOrg remains a mystery to me... and why the error message mentions I cannot use a personal account even when both settings are explicitly set to 'AzureADandPersonalMicrosoftAccount'.
Then again, the whole notion of 'personal' vs 'work/school' accounts is a small disaster in my mind ;)

Is this the correct summary:
My "anything@hotmail.com" counts as a personal Microsoft account. But as soon as I invite that as a guest account into my Azure AD, it counts as a "organization" account, which is the only supported type for authorization to a key vault (since you'd need to be able to define the access policies)?

@bgavrilMS
Copy link
Member

Yes, @Hotmail, @outlook.com, @live.com (and a few more aliases) are "Microsoft" accounts (aka live accounts or MSA accounts or personal accounts). They are all in one big tenant (the MSA tenant).

Work and School accounts are tied to an organization, e.g. joe.blogs@contoso.com is an account in the contoso tenant. Each organization that hosts their directory with AAD gets their own tenant.

In MSAL, you configure the authority as:

  • only users from your Work and School tenant, then use an authority like https://login.microsotonline.com/<my_tenant_id>
  • any Work and School tenant (authority https://login.microsoftonline.com/organizations)
  • only Microsoft personal accounts (i.e. personal accounts) - https://login.microsoftonline.com/consumers
  • Personal acounts + any Work and School account - https://login.microsoftonline.com/common

In the App registration portal in Azure, you must also configure the audience in a similar way (sorry I don't remember the exact setting, but I can look if you want).

This wiki page describes the identity providers: https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Register-your-application-with-Azure-Active-Directory

This wiki page offers a few details about audience: https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Client-Applications#application-audience

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Development

No branches or pull requests

4 participants