diff --git a/src/Microsoft.Agents.SDK.sln b/src/Microsoft.Agents.SDK.sln index 3bb074c6..e3b52f6a 100644 --- a/src/Microsoft.Agents.SDK.sln +++ b/src/Microsoft.Agents.SDK.sln @@ -338,11 +338,7 @@ Global {BC5EFA6C-7EB5-4803-B7C5-093892E9DBB8}.Debug|Any CPU.Build.0 = Debug|Any CPU {BC5EFA6C-7EB5-4803-B7C5-093892E9DBB8}.Release|Any CPU.ActiveCfg = Release|Any CPU {BC5EFA6C-7EB5-4803-B7C5-093892E9DBB8}.Release|Any CPU.Build.0 = Release|Any CPU - {B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F}.Release|Any CPU.Build.0 = Release|Any CPU - {BF587311-1240-889C-E6AE-ED61A6ED2B37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BF587311-1240-889C-E6AE-ED61A6ED2B37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BF587311-1240-889C-E6AE-ED61A6ED2B37}.Debug|Any CPU.Build.0 = Debug|Any CPU {BF587311-1240-889C-E6AE-ED61A6ED2B37}.Release|Any CPU.ActiveCfg = Release|Any CPU {BF587311-1240-889C-E6AE-ED61A6ED2B37}.Release|Any CPU.Build.0 = Release|Any CPU @@ -354,6 +350,10 @@ Global {153EA430-9914-18E7-409F-7292CB1914AB}.Debug|Any CPU.Build.0 = Debug|Any CPU {153EA430-9914-18E7-409F-7292CB1914AB}.Release|Any CPU.ActiveCfg = Release|Any CPU {153EA430-9914-18E7-409F-7292CB1914AB}.Release|Any CPU.Build.0 = Release|Any CPU + {B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -417,10 +417,10 @@ Global {7D1A1CE5-6D9B-4D31-AC77-C3B1787F575D} = {AD743B78-D61F-4FBF-B620-FA83CE599A50} {06E490F7-F0BB-E3C4-54FE-5210627292A1} = {183D0E91-B84E-46D7-B653-6D85B4CCF804} {BC5EFA6C-7EB5-4803-B7C5-093892E9DBB8} = {183D0E91-B84E-46D7-B653-6D85B4CCF804} - {B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F} = {AD743B78-D61F-4FBF-B620-FA83CE599A50} - {BF587311-1240-889C-E6AE-ED61A6ED2B37} = {183D0E91-B84E-46D7-B653-6D85B4CCF804} + {BF587311-1240-889C-E6AE-ED61A6ED2B37} = {183D0E91-B84E-46D7-B653-6D85B4CCF804} {697C1093-D392-8ABC-2BC8-F955022B1853} = {183D0E91-B84E-46D7-B653-6D85B4CCF804} {153EA430-9914-18E7-409F-7292CB1914AB} = {183D0E91-B84E-46D7-B653-6D85B4CCF804} + {B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F} = {AD743B78-D61F-4FBF-B620-FA83CE599A50} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F1E8E538-309A-46F8-9CE7-AEC6589FAE60} diff --git a/src/libraries/Authentication/Authentication.Msal/MsalAuth.cs b/src/libraries/Authentication/Authentication.Msal/MsalAuth.cs index d2f3f12a..3fcbbfd6 100644 --- a/src/libraries/Authentication/Authentication.Msal/MsalAuth.cs +++ b/src/libraries/Authentication/Authentication.Msal/MsalAuth.cs @@ -93,6 +93,10 @@ public async Task GetAccessTokenAsync(string resourceUrl, IList ExecuteAuthenticationResults authResultPayload = null; if (msalAuthClient is IConfidentialClientApplication msalConfidentialClient) { + if (localScopes.Length == 0) { + throw new ArgumentException("At least one Scope is required for Client Authentication."); + } + var authResult = await msalConfidentialClient.AcquireTokenForClient(localScopes).WithForceRefresh(true).ExecuteAsync().ConfigureAwait(false); authResultPayload = new ExecuteAuthenticationResults() { @@ -204,21 +208,26 @@ private object CreateClientApplication() private string[] ResolveScopesList(Uri instanceUrl, IList scopes = null) { IList _localScopesResolver = new List(); + if (scopes != null && scopes.Count > 0) { return scopes.ToArray(); } else { - List templist = new List(); - foreach (var scope in _connectionSettings.Scopes) + var templist = new List(); + + if (_connectionSettings.Scopes != null) { - var scopePlaceholder = scope; - if (scopePlaceholder.ToLower().Contains("{instance}")) + foreach (var scope in _connectionSettings.Scopes) { - scopePlaceholder = scopePlaceholder.Replace("{instance}", $"{instanceUrl.Scheme}://{instanceUrl.Host}"); + var scopePlaceholder = scope; + if (scopePlaceholder.ToLower().Contains("{instance}")) + { + scopePlaceholder = scopePlaceholder.Replace("{instance}", $"{instanceUrl.Scheme}://{instanceUrl.Host}"); + } + templist.Add(scopePlaceholder); } - templist.Add(scopePlaceholder); } return templist.ToArray(); } diff --git a/src/tests/Microsoft.Agents.Authentication.Msal.Tests/MsalAuthTests.cs b/src/tests/Microsoft.Agents.Authentication.Msal.Tests/MsalAuthTests.cs index 3fdf20ba..ee86344e 100644 --- a/src/tests/Microsoft.Agents.Authentication.Msal.Tests/MsalAuthTests.cs +++ b/src/tests/Microsoft.Agents.Authentication.Msal.Tests/MsalAuthTests.cs @@ -64,9 +64,36 @@ public void Constructor_ShouldThrowOnNullConfiguration() [Fact] public async Task GetAccessTokenAsync_ShouldThrowOnMalformedUri() { - var msal = new MsalAuth(_service.Object, _configuration.GetSection(SettingsSection)); + var msalAuth = new MsalAuth(_service.Object, _configuration.GetSection(SettingsSection)); + + await Assert.ThrowsAsync(() => msalAuth.GetAccessTokenAsync(null, _scopes, false)); + } + + [Fact] + public async Task GetAccessTokenAsync_ShouldThrowOnNullScopesForClientCredentials() + { + var options = new Mock>(); + + var returnedOptions = new MsalAuthConfigurationOptions + { + MSALEnabledLogPII = false + }; + options.Setup(x => x.Value).Returns(returnedOptions).Verifiable(Times.Exactly(2)); - await Assert.ThrowsAsync(() => msal.GetAccessTokenAsync(null, _scopes, false)); + var logger = new Mock>(); + + var service = new Mock(); + service.Setup(x => x.GetService(typeof(IOptions))) + .Returns(options.Object) + .Verifiable(Times.Exactly(2)); + service.Setup(x => x.GetService(typeof(ILogger))) + .Returns(logger.Object) + .Verifiable(Times.Once); + + var msalAuth = new MsalAuth(service.Object, _configuration.GetSection(SettingsSection)); + + await Assert.ThrowsAsync(() => msalAuth.GetAccessTokenAsync(ResourceUrl, null, false)); + Mock.Verify(options, service); } [Fact]