From 28fdf762d4bf59db9920df0b32649040d36f7431 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Mon, 1 Feb 2021 15:10:55 +0000 Subject: [PATCH] msauth: rename resource to scopes and drop remote URI Rename the resource parameter to the MSAuth component to scopes, which is the AAD "v2" concept. Also drop the remote URI parameter which is no longer needed. --- .../AzureReposHostProviderTests.cs | 4 ++-- .../AzureDevOpsConstants.cs | 8 ++++++-- .../AzureReposHostProvider.cs | 3 +-- .../MicrosoftAuthenticationTests.cs | 5 ++--- .../Authentication/MicrosoftAuthentication.cs | 20 +++---------------- 5 files changed, 14 insertions(+), 26 deletions(-) diff --git a/src/shared/Microsoft.AzureRepos.Tests/AzureReposHostProviderTests.cs b/src/shared/Microsoft.AzureRepos.Tests/AzureReposHostProviderTests.cs index 129a3d67f..ea86fd11a 100644 --- a/src/shared/Microsoft.AzureRepos.Tests/AzureReposHostProviderTests.cs +++ b/src/shared/Microsoft.AzureRepos.Tests/AzureReposHostProviderTests.cs @@ -153,7 +153,7 @@ public async Task AzureReposProvider_GetCredentialAsync_ReturnsCredential() var authorityUrl = "https://login.microsoftonline.com/common"; var expectedClientId = AzureDevOpsConstants.AadClientId; var expectedRedirectUri = AzureDevOpsConstants.AadRedirectUri; - var expectedResource = AzureDevOpsConstants.AadResourceId; + var expectedScopes = AzureDevOpsConstants.AzureDevOpsDefaultScopes; var accessToken = "ACCESS-TOKEN"; var personalAccessToken = "PERSONAL-ACCESS-TOKEN"; var authResult = CreateAuthResult("john.doe", accessToken); @@ -167,7 +167,7 @@ public async Task AzureReposProvider_GetCredentialAsync_ReturnsCredential() .ReturnsAsync(personalAccessToken); var msAuthMock = new Mock(); - msAuthMock.Setup(x => x.GetTokenAsync(authorityUrl, expectedClientId, expectedRedirectUri, expectedResource, remoteUri, null)) + msAuthMock.Setup(x => x.GetTokenAsync(authorityUrl, expectedClientId, expectedRedirectUri, expectedScopes, null)) .ReturnsAsync(authResult); var provider = new AzureReposHostProvider(context, azDevOpsMock.Object, msAuthMock.Object); diff --git a/src/shared/Microsoft.AzureRepos/AzureDevOpsConstants.cs b/src/shared/Microsoft.AzureRepos/AzureDevOpsConstants.cs index 886ab9805..00cd9c908 100644 --- a/src/shared/Microsoft.AzureRepos/AzureDevOpsConstants.cs +++ b/src/shared/Microsoft.AzureRepos/AzureDevOpsConstants.cs @@ -6,8 +6,12 @@ namespace Microsoft.AzureRepos { internal static class AzureDevOpsConstants { - // Azure DevOps's resource ID - public const string AadResourceId = "499b84ac-1321-427f-aa17-267ca6975798"; + + // AAD environment authority base URL + public const string AadAuthorityBaseUrl = "https://login.microsoftonline.com"; + + // Azure DevOps's app ID + default scopes + public static readonly string[] AzureDevOpsDefaultScopes = {"499b84ac-1321-427f-aa17-267ca6975798/.default"}; // Visual Studio's client ID // We share this to be able to consume existing access tokens from the VS caches diff --git a/src/shared/Microsoft.AzureRepos/AzureReposHostProvider.cs b/src/shared/Microsoft.AzureRepos/AzureReposHostProvider.cs index ac95ec7c9..55f353ad2 100644 --- a/src/shared/Microsoft.AzureRepos/AzureReposHostProvider.cs +++ b/src/shared/Microsoft.AzureRepos/AzureReposHostProvider.cs @@ -155,8 +155,7 @@ private async Task GenerateCredentialAsync(InputArguments input) authAuthority, AzureDevOpsConstants.AadClientId, AzureDevOpsConstants.AadRedirectUri, - AzureDevOpsConstants.AadResourceId, - remoteUri, + AzureDevOpsConstants.AzureDevOpsDefaultScopes, null); _context.Trace.WriteLineSecrets( $"Acquired Azure access token. Account='{result.AccountUpn}' Token='{{0}}'", new object[] {result.AccessToken}); diff --git a/src/shared/Microsoft.Git.CredentialManager.Tests/Authentication/MicrosoftAuthenticationTests.cs b/src/shared/Microsoft.Git.CredentialManager.Tests/Authentication/MicrosoftAuthenticationTests.cs index a18cac3ea..0fe29cec5 100644 --- a/src/shared/Microsoft.Git.CredentialManager.Tests/Authentication/MicrosoftAuthenticationTests.cs +++ b/src/shared/Microsoft.Git.CredentialManager.Tests/Authentication/MicrosoftAuthenticationTests.cs @@ -15,8 +15,7 @@ public async System.Threading.Tasks.Task MicrosoftAuthentication_GetAccessTokenA const string authority = "https://login.microsoftonline.com/common"; const string clientId = "C9E8FDA6-1D46-484C-917C-3DBD518F27C3"; Uri redirectUri = new Uri("https://localhost"); - const string resource = "https://graph.microsoft.com"; - Uri remoteUri = new Uri("https://example.com"); + string[] scopes = {"user.read"}; const string userName = null; // No user to ensure we do not use an existing token var context = new TestCommandContext @@ -27,7 +26,7 @@ public async System.Threading.Tasks.Task MicrosoftAuthentication_GetAccessTokenA var msAuth = new MicrosoftAuthentication(context); await Assert.ThrowsAsync( - () => msAuth.GetTokenAsync(authority, clientId, redirectUri, resource, remoteUri, userName)); + () => msAuth.GetTokenAsync(authority, clientId, redirectUri, scopes, userName)); } } } diff --git a/src/shared/Microsoft.Git.CredentialManager/Authentication/MicrosoftAuthentication.cs b/src/shared/Microsoft.Git.CredentialManager/Authentication/MicrosoftAuthentication.cs index 239a0d598..c33d6eed0 100644 --- a/src/shared/Microsoft.Git.CredentialManager/Authentication/MicrosoftAuthentication.cs +++ b/src/shared/Microsoft.Git.CredentialManager/Authentication/MicrosoftAuthentication.cs @@ -13,8 +13,8 @@ namespace Microsoft.Git.CredentialManager.Authentication { public interface IMicrosoftAuthentication { - Task GetTokenAsync(string authority, string clientId, Uri redirectUri, string resource, - Uri remoteUri, string userName); + Task GetTokenAsync(string authority, string clientId, Uri redirectUri, + string[] scopes, string userName); } public interface IMicrosoftAuthenticationResult @@ -46,21 +46,7 @@ public MicrosoftAuthentication(ICommandContext context) #region IMicrosoftAuthentication public async Task GetTokenAsync( - string authority, string clientId, Uri redirectUri, string resource, Uri remoteUri, string userName) - { - // Try to acquire an access token in the current process - string[] scopes = { $"{resource}/.default" }; - return await GetTokenInProcAsync(authority, clientId, redirectUri, scopes, userName); - } - - #endregion - - #region Authentication strategies - - /// - /// Obtain an access token using MSAL running inside the current process. - /// - private async Task GetTokenInProcAsync(string authority, string clientId, Uri redirectUri, string[] scopes, string userName) + string authority, string clientId, Uri redirectUri, string[] scopes, string userName) { IPublicClientApplication app = await CreatePublicClientApplicationAsync(authority, clientId, redirectUri);