diff --git a/Microsoft.Kiota.sln b/Microsoft.Kiota.sln
index c2087eab..24c7dba3 100644
--- a/Microsoft.Kiota.sln
+++ b/Microsoft.Kiota.sln
@@ -14,31 +14,40 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
SUPPORT.md = SUPPORT.md
EndProjectSection
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Kiota.Abstractions", "src\abstractions\Microsoft.Kiota.Abstractions.csproj", "{7D843C30-B856-49BD-97BC-B74F9F234EF9}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Kiota.Abstractions.Tests", "tests\abstractions\Microsoft.Kiota.Abstractions.Tests.csproj", "{B112E9CF-055E-45FB-A32F-25CAB57936DB}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Kiota.Abstractions", "src\abstractions\Microsoft.Kiota.Abstractions.csproj", "{61B7F639-6456-41CA-B53E-492115888F84}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Kiota.Authentication.Azure", "src\authentication\azure\Microsoft.Kiota.Authentication.Azure.csproj", "{ED943ED1-CC3E-41B9-BE79-C3C301D2267B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Kiota.Authentication.Azure.Tests", "tests\authentication\azure\Microsoft.Kiota.Authentication.Azure.Tests.csproj", "{71161CE4-C748-4CD3-A5ED-A2B806B24360}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {7D843C30-B856-49BD-97BC-B74F9F234EF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {7D843C30-B856-49BD-97BC-B74F9F234EF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {7D843C30-B856-49BD-97BC-B74F9F234EF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {7D843C30-B856-49BD-97BC-B74F9F234EF9}.Release|Any CPU.Build.0 = Release|Any CPU
{B112E9CF-055E-45FB-A32F-25CAB57936DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B112E9CF-055E-45FB-A32F-25CAB57936DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B112E9CF-055E-45FB-A32F-25CAB57936DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B112E9CF-055E-45FB-A32F-25CAB57936DB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {61B7F639-6456-41CA-B53E-492115888F84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {61B7F639-6456-41CA-B53E-492115888F84}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {61B7F639-6456-41CA-B53E-492115888F84}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {61B7F639-6456-41CA-B53E-492115888F84}.Release|Any CPU.Build.0 = Release|Any CPU
+ {ED943ED1-CC3E-41B9-BE79-C3C301D2267B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {ED943ED1-CC3E-41B9-BE79-C3C301D2267B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {ED943ED1-CC3E-41B9-BE79-C3C301D2267B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {ED943ED1-CC3E-41B9-BE79-C3C301D2267B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {71161CE4-C748-4CD3-A5ED-A2B806B24360}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {71161CE4-C748-4CD3-A5ED-A2B806B24360}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {71161CE4-C748-4CD3-A5ED-A2B806B24360}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {71161CE4-C748-4CD3-A5ED-A2B806B24360}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {7D843C30-B856-49BD-97BC-B74F9F234EF9} = {812D9C21-411D-4987-AB8E-C96185F01AD0}
- EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B0E38E50-7BC8-4E28-BDAC-BF38F7AF2CD2}
EndGlobalSection
diff --git a/README.md b/README.md
index a691079b..ed25bbeb 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,7 @@ Read more about Kiota [here](https://github.com/microsoft/kiota/blob/main/README
## Libraries
1. [Abstractions](./src/abstractions/README.md)
+1. [Authentication - Azure](./src/authentication/azure/README.md)
## Debugging
diff --git a/src/abstractions/README.md b/src/abstractions/README.md
index 3417c172..6e48fdc1 100644
--- a/src/abstractions/README.md
+++ b/src/abstractions/README.md
@@ -11,7 +11,7 @@ Read more about Kiota [here](https://github.com/microsoft/kiota/blob/main/README
## Using the Abstractions Library
```shell
-dotnet add package Microsoft.Kiota.Abstractions --prerelease
+dotnet add package Microsoft.Kiota.Abstractions
```
## Debugging
@@ -38,4 +38,4 @@ This project may contain trademarks or logos for projects, products, or services
trademarks or logos is subject to and must follow
[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/legal/intellectualproperty/trademarks/usage/general).
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
-Any use of third-party trademarks or logos are subject to those third-party's policies.
\ No newline at end of file
+Any use of third-party trademarks or logos are subject to those third-party's policies.
diff --git a/src/authentication/azure/35MSSharedLib1024.snk b/src/authentication/azure/35MSSharedLib1024.snk
new file mode 100644
index 00000000..695f1b38
Binary files /dev/null and b/src/authentication/azure/35MSSharedLib1024.snk differ
diff --git a/src/authentication/azure/AzureIdentityAccessTokenProvider.cs b/src/authentication/azure/AzureIdentityAccessTokenProvider.cs
new file mode 100644
index 00000000..b8a0abb0
--- /dev/null
+++ b/src/authentication/azure/AzureIdentityAccessTokenProvider.cs
@@ -0,0 +1,103 @@
+// ------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
+// ------------------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Azure.Core;
+using Microsoft.Kiota.Abstractions.Authentication;
+
+namespace Microsoft.Kiota.Authentication.Azure;
+///
+/// Provides an implementation of for Azure.Identity.
+///
+public class AzureIdentityAccessTokenProvider : IAccessTokenProvider, IDisposable
+{
+ private static readonly object BoxedTrue = true;
+ private static readonly object BoxedFalse = false;
+
+ private readonly TokenCredential _credential;
+ private readonly ActivitySource _activitySource;
+ private readonly HashSet _scopes;
+ ///
+ public AllowedHostsValidator AllowedHostsValidator { get; protected set; }
+
+ ///
+ /// The constructor
+ ///
+ /// The credential implementation to use to obtain the access token.
+ /// The list of allowed hosts for which to request access tokens.
+ /// The scopes to request the access token for.
+ /// The observability options to use for the authentication provider.
+ public AzureIdentityAccessTokenProvider(TokenCredential credential, string []? allowedHosts = null, ObservabilityOptions? observabilityOptions = null, params string[] scopes)
+ {
+ _credential = credential ?? throw new ArgumentNullException(nameof(credential));
+
+ AllowedHostsValidator = new AllowedHostsValidator(allowedHosts);
+
+ if(scopes == null)
+ _scopes = new();
+ else
+ _scopes = new(scopes, StringComparer.OrdinalIgnoreCase);
+
+ _activitySource = new((observabilityOptions ?? new()).TracerInstrumentationName);
+ }
+
+ private const string ClaimsKey = "claims";
+
+ private readonly HashSet _localHostStrings = new HashSet(StringComparer.OrdinalIgnoreCase)
+ {
+ "localhost",
+ "[::1]",
+ "::1",
+ "127.0.0.1"
+ };
+
+ ///
+ public async Task GetAuthorizationTokenAsync(Uri uri, Dictionary? additionalAuthenticationContext = default, CancellationToken cancellationToken = default)
+ {
+ using var span = _activitySource?.StartActivity(nameof(GetAuthorizationTokenAsync));
+ if(!AllowedHostsValidator.IsUrlHostValid(uri)) {
+ span?.SetTag("com.microsoft.kiota.authentication.is_url_valid", BoxedFalse);
+ return string.Empty;
+ }
+
+ if(!uri.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase) && !_localHostStrings.Contains(uri.Host)) {
+ span?.SetTag("com.microsoft.kiota.authentication.is_url_valid", BoxedFalse);
+ throw new ArgumentException("Only https is supported");
+ }
+ span?.SetTag("com.microsoft.kiota.authentication.is_url_valid", BoxedTrue);
+
+ string? decodedClaim = null;
+ if (additionalAuthenticationContext is not null &&
+ additionalAuthenticationContext.ContainsKey(ClaimsKey) &&
+ additionalAuthenticationContext[ClaimsKey] is string claims) {
+ span?.SetTag("com.microsoft.kiota.authentication.additional_claims_provided", BoxedTrue);
+ var decodedBase64Bytes = Convert.FromBase64String(claims);
+ decodedClaim = Encoding.UTF8.GetString(decodedBase64Bytes);
+ } else
+ span?.SetTag("com.microsoft.kiota.authentication.additional_claims_provided", BoxedFalse);
+
+ string[] scopes;
+ if (_scopes.Count > 0) {
+ scopes = new string[_scopes.Count];
+ _scopes.CopyTo(scopes);
+ } else
+ scopes = [ $"{uri.Scheme}://{uri.Host}/.default" ];
+ span?.SetTag("com.microsoft.kiota.authentication.scopes", string.Join(",", scopes));
+
+ var result = await _credential.GetTokenAsync(new TokenRequestContext(scopes, claims: decodedClaim), cancellationToken).ConfigureAwait(false);
+ return result.Token;
+ }
+
+ ///
+ public void Dispose()
+ {
+ _activitySource?.Dispose();
+ GC.SuppressFinalize(this);
+ }
+}
diff --git a/src/authentication/azure/AzureIdentityAuthenticationProvider.cs b/src/authentication/azure/AzureIdentityAuthenticationProvider.cs
new file mode 100644
index 00000000..d5d083e4
--- /dev/null
+++ b/src/authentication/azure/AzureIdentityAuthenticationProvider.cs
@@ -0,0 +1,25 @@
+// ------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
+// ------------------------------------------------------------------------------
+
+using Azure.Core;
+using Microsoft.Kiota.Abstractions.Authentication;
+
+namespace Microsoft.Kiota.Authentication.Azure;
+///
+/// The implementation that supports implementations of from Azure.Identity.
+///
+public class AzureIdentityAuthenticationProvider : BaseBearerTokenAuthenticationProvider
+{
+ ///
+ /// The constructor
+ ///
+ /// The credential implementation to use to obtain the access token.
+ /// The list of allowed hosts for which to request access tokens.
+ /// The scopes to request the access token for.
+ /// The observability options to use for the authentication provider.
+ public AzureIdentityAuthenticationProvider(TokenCredential credential, string[]? allowedHosts = null, ObservabilityOptions? observabilityOptions = null, params string[] scopes)
+ : base(new AzureIdentityAccessTokenProvider(credential, allowedHosts, observabilityOptions, scopes))
+ {
+ }
+}
diff --git a/src/authentication/azure/Microsoft.Kiota.Authentication.Azure.csproj b/src/authentication/azure/Microsoft.Kiota.Authentication.Azure.csproj
new file mode 100644
index 00000000..eeffa37a
--- /dev/null
+++ b/src/authentication/azure/Microsoft.Kiota.Authentication.Azure.csproj
@@ -0,0 +1,67 @@
+
+
+
+
+ Kiota authentication provider implementation with Azure Identity.
+ © Microsoft Corporation. All rights reserved.
+ Kiota Azure Identity Authentication Library for dotnet
+ Microsoft
+
+ netstandard2.0;netstandard2.1;net5.0;net6.0;net8.0
+ latest
+ true
+ http://go.microsoft.com/fwlink/?LinkID=288890
+ https://github.com/microsoft/kiota-authentication-azure-dotnet
+ https://aka.ms/kiota/docs
+ true
+ true
+ 1.1.7
+
+ true
+ true
+
+
+ false
+ false
+ 35MSSharedLib1024.snk
+ latest
+ enable
+ true
+
+ https://github.com/microsoft/kiota-authentication-azure-dotnet/releases
+
+ true
+ MIT
+ README.md
+ $(NoWarn);NU5048;NETSDK1138
+
+
+ true
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+ True
+
+
+
+
+
diff --git a/src/authentication/azure/ObservabilityOptions.cs b/src/authentication/azure/ObservabilityOptions.cs
new file mode 100644
index 00000000..28c31cd4
--- /dev/null
+++ b/src/authentication/azure/ObservabilityOptions.cs
@@ -0,0 +1,17 @@
+// ------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
+// ------------------------------------------------------------------------------
+
+using System;
+
+namespace Microsoft.Kiota.Authentication.Azure;
+///
+/// Holds the tracing, metrics and logging configuration for the authentication provider
+///
+public class ObservabilityOptions {
+ private static readonly Lazy _name = new Lazy(() => typeof(ObservabilityOptions).Namespace!);
+ ///
+ /// Gets the observability name to use for the tracer
+ ///
+ public string TracerInstrumentationName => _name.Value;
+}
diff --git a/src/authentication/azure/README.md b/src/authentication/azure/README.md
new file mode 100644
index 00000000..a691768b
--- /dev/null
+++ b/src/authentication/azure/README.md
@@ -0,0 +1,41 @@
+# Kiota Azure Identity authentication provider library for dotnet
+
+[![Build and Test](https://github.com/microsoft/kiota-authentication-azure-dotnet/actions/workflows/build-and-test.yml/badge.svg?branch=main)](https://github.com/microsoft/kiota-authentication-azure-dotnet/actions/workflows/build-and-test.yml) [![NuGet Version](https://buildstats.info/nuget/Microsoft.Kiota.Authentication.Azure?includePreReleases=true)](https://www.nuget.org/packages/Microsoft.Kiota.Authentication.Azure/)
+
+The Kiota Azure Identity authentication provider library for dotnet is the authentication provider implementation with [Azure.Identity](https://docs.microsoft.com/en-us/dotnet/api/overview/azure/identity-readme).
+
+A [Kiota](https://github.com/microsoft/kiota) generated project will need a reference to a authentication provider library to authenticate HTTP requests to an API endpoint.
+
+Read more about Kiota [here](https://github.com/microsoft/kiota/blob/main/README.md).
+
+## Using Azure Identity authentication provider library for dotnet
+
+```shell
+dotnet add package Microsoft.Kiota.Authentication.Azure
+```
+
+## Debugging
+
+If you are using Visual Studio Code as your IDE, the **launch.json** file already contains the configuration to build and test the library. Otherwise, you can open the **Microsoft.Kiota.Authentication.Azure.sln** with Visual Studio.
+
+## Contributing
+
+This project welcomes contributions and suggestions. Most contributions require you to agree to a
+Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
+the rights to use your contribution. For details, visit [https://cla.opensource.microsoft.com](https://cla.opensource.microsoft.com).
+
+When you submit a pull request, a CLA bot will automatically determine whether you need to provide
+a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
+provided by the bot. You will only need to do this once across all repos using our CLA.
+
+This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
+For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
+contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
+
+## Trademarks
+
+This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
+trademarks or logos is subject to and must follow
+[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/legal/intellectualproperty/trademarks/usage/general).
+Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
+Any use of third-party trademarks or logos are subject to those third-party's policies.
diff --git a/tests/authentication/azure/AzureIdentityAuthenticationProviderTests.cs b/tests/authentication/azure/AzureIdentityAuthenticationProviderTests.cs
new file mode 100644
index 00000000..2c2e63c3
--- /dev/null
+++ b/tests/authentication/azure/AzureIdentityAuthenticationProviderTests.cs
@@ -0,0 +1,129 @@
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Moq;
+using Xunit;
+using Azure.Core;
+using Microsoft.Kiota.Abstractions;
+
+namespace Microsoft.Kiota.Authentication.Azure.Tests;
+public class AzureIdentityAuthenticationProviderTests
+{
+ [Fact]
+ public void ConstructorThrowsArgumentNullExceptionOnNullTokenCredential()
+ {
+ // Arrange
+ var exception = Assert.Throws(() => new AzureIdentityAccessTokenProvider(null, null));
+
+ // Assert
+ Assert.Equal("credential", exception.ParamName);
+ }
+
+ [Theory]
+ [InlineData("https://localhost", "")]
+ [InlineData("https://graph.microsoft.com", "token")]
+ [InlineData("https://graph.microsoft.com/v1.0/me", "token")]
+ public async Task GetAuthorizationTokenAsyncGetsToken(string url, string expectedToken)
+ {
+ // Arrange
+ var uri = new Uri(url);
+ var mockTokenCredential = new Mock();
+ mockTokenCredential.Setup(credential => credential.GetTokenAsync(It.IsAny(), It.IsAny())).Returns(new ValueTask(new AccessToken(expectedToken, DateTimeOffset.Now)));
+ var azureIdentityAuthenticationProvider = new AzureIdentityAccessTokenProvider(mockTokenCredential.Object);
+
+ // Act
+ var token = await azureIdentityAuthenticationProvider.GetAuthorizationTokenAsync(uri);
+
+ // Assert
+ Assert.Equal(expectedToken, token);
+ mockTokenCredential.Verify(x => x.GetTokenAsync(It.Is(t =>
+ t.Scopes.Any(s => $"{uri.Scheme}://{uri.Host}/.default".Equals(s, StringComparison.OrdinalIgnoreCase))), It.IsAny()));
+ }
+
+ [Theory]
+ [InlineData("https://localhost", "")]
+ [InlineData("https://graph.microsoft.com", "token")]
+ [InlineData("https://graph.microsoft.com/v1.0/me", "token")]
+ public async Task AuthenticateRequestAsyncSetsBearerHeader(string url, string expectedToken)
+ {
+ // Arrange
+ var mockTokenCredential = new Mock();
+ mockTokenCredential.Setup(credential => credential.GetTokenAsync(It.IsAny(), It.IsAny())).Returns(new ValueTask(new AccessToken(expectedToken, DateTimeOffset.Now)));
+ var azureIdentityAuthenticationProvider = new AzureIdentityAuthenticationProvider(mockTokenCredential.Object, scopes: "User.Read");
+ var testRequest = new RequestInformation()
+ {
+ HttpMethod = Method.GET,
+ URI = new Uri(url)
+ };
+ Assert.Empty(testRequest.Headers); // header collection is empty
+
+ // Act
+ await azureIdentityAuthenticationProvider.AuthenticateRequestAsync(testRequest);
+
+ // Assert
+ if(string.IsNullOrEmpty(expectedToken))
+ {
+ Assert.Empty(testRequest.Headers); // header collection is still empty
+ }
+ else
+ {
+ Assert.NotEmpty(testRequest.Headers); // header collection is no longer empty
+ Assert.Equal("Authorization", testRequest.Headers.First().Key); // First element is Auth header
+ Assert.Equal($"Bearer {expectedToken}", testRequest.Headers["Authorization"].First()); // First element is Auth header
+ }
+ }
+
+ [Fact]
+ public async Task GetAuthorizationTokenAsyncThrowsExcpetionForNonHTTPsUrl()
+ {
+ // Arrange
+ var mockTokenCredential = new Mock();
+ mockTokenCredential.Setup(credential => credential.GetTokenAsync(It.IsAny(), It.IsAny())).Returns(new ValueTask(new AccessToken(string.Empty, DateTimeOffset.Now)));
+ var azureIdentityAuthenticationProvider = new AzureIdentityAccessTokenProvider(mockTokenCredential.Object);
+
+ var nonHttpsUrl = "http://graph.microsoft.com";
+
+ // Assert
+ var exception = await Assert.ThrowsAsync(() => azureIdentityAuthenticationProvider.GetAuthorizationTokenAsync(new Uri(nonHttpsUrl)));
+ Assert.Equal("Only https is supported", exception.Message);
+ }
+
+ [Theory]
+ [InlineData("http://localhost/test")]
+ [InlineData("http://localhost:8080/test")]
+ [InlineData("http://127.0.0.1:8080/test")]
+ [InlineData("http://127.0.0.1/test")]
+ public async Task GetAuthorizationTokenAsyncDoesNotThrowsExcpetionForNonHTTPsUrlIfLocalHost(string nonHttpsUrl)
+ {
+ // Arrange
+ var mockTokenCredential = new Mock();
+ mockTokenCredential.Setup(credential => credential.GetTokenAsync(It.IsAny(), It.IsAny())).Returns(new ValueTask(new AccessToken(string.Empty, DateTimeOffset.Now)));
+ var azureIdentityAuthenticationProvider = new AzureIdentityAccessTokenProvider(mockTokenCredential.Object);
+
+ // Assert
+ var token = await azureIdentityAuthenticationProvider.GetAuthorizationTokenAsync(new Uri(nonHttpsUrl));
+ Assert.Empty(token);
+ }
+ [Fact]
+ public async Task AddsClaimsToTheTokenContext()
+ {
+ var mockTokenCredential = new Mock();
+ mockTokenCredential.Setup(credential => credential.GetTokenAsync(It.IsAny(), It.IsAny()))
+ .Returns((context, cToken) => {
+ Assert.NotNull(context.Claims);
+ return new ValueTask(new AccessToken(string.Empty, DateTimeOffset.Now));
+ });
+ var azureIdentityAuthenticationProvider = new AzureIdentityAuthenticationProvider(mockTokenCredential.Object, scopes: "User.Read");
+ var testRequest = new RequestInformation()
+ {
+ HttpMethod = Method.GET,
+ URI = new Uri("https://graph.microsoft.com/v1.0/me")
+ };
+ Assert.Empty(testRequest.Headers); // header collection is empty
+
+ // Act
+ await azureIdentityAuthenticationProvider.AuthenticateRequestAsync(testRequest, new() { {"claims", "eyJhY2Nlc3NfdG9rZW4iOnsibmJmIjp7ImVzc2VudGlhbCI6dHJ1ZSwgInZhbHVlIjoiMTY1MjgxMzUwOCJ9fX0="}});
+ mockTokenCredential.Verify(x => x.GetTokenAsync(It.IsAny(), It.IsAny()), Times.Once);
+ }
+}
diff --git a/tests/authentication/azure/Microsoft.Kiota.Authentication.Azure.Tests.csproj b/tests/authentication/azure/Microsoft.Kiota.Authentication.Azure.Tests.csproj
new file mode 100644
index 00000000..c0412b9d
--- /dev/null
+++ b/tests/authentication/azure/Microsoft.Kiota.Authentication.Azure.Tests.csproj
@@ -0,0 +1,33 @@
+
+
+
+ net8.0;net462
+ latest
+ false
+ true
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+