AAD: change to CredentialEnvelope to expose Expiration (#2306)

This commit is contained in:
Timothy Mothra 2021-06-21 15:24:12 -07:00 коммит произвёл GitHub
Родитель eb1c2cc423
Коммит 4af30fd1b3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
10 изменённых файлов: 359 добавлений и 93 удалений

Просмотреть файл

@ -1,5 +1,12 @@
abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string
abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<string>
abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken
abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken>
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.AuthToken() -> void
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.AuthToken(string token, System.DateTimeOffset expiresOn) -> void
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.ExpiresOn.get -> System.DateTimeOffset
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.ExpiresOn.set -> void
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.Token.get -> string
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.Token.set -> void
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope
@ -7,4 +14,8 @@ Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetAzureToken
Microsoft.ApplicationInsights.Channel.IAsyncFlushable
Microsoft.ApplicationInsights.Channel.IAsyncFlushable.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<bool>
Microsoft.ApplicationInsights.Channel.InMemoryChannel.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<bool>
Microsoft.ApplicationInsights.TelemetryClient.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<bool>
Microsoft.ApplicationInsights.TelemetryClient.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<bool>
override Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.Equals(object obj) -> bool
override Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.GetHashCode() -> int
static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.operator !=(Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken left, Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken right) -> bool
static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.operator ==(Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken left, Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken right) -> bool

Просмотреть файл

@ -1,5 +1,12 @@
abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string
abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<string>
abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken
abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken>
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.AuthToken() -> void
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.AuthToken(string token, System.DateTimeOffset expiresOn) -> void
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.ExpiresOn.get -> System.DateTimeOffset
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.ExpiresOn.set -> void
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.Token.get -> string
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.Token.set -> void
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope
@ -7,4 +14,8 @@ Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetAzureToken
Microsoft.ApplicationInsights.Channel.IAsyncFlushable
Microsoft.ApplicationInsights.Channel.IAsyncFlushable.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<bool>
Microsoft.ApplicationInsights.Channel.InMemoryChannel.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<bool>
Microsoft.ApplicationInsights.TelemetryClient.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<bool>
Microsoft.ApplicationInsights.TelemetryClient.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<bool>
override Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.Equals(object obj) -> bool
override Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.GetHashCode() -> int
static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.operator !=(Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken left, Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken right) -> bool
static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.operator ==(Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken left, Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken right) -> bool

Просмотреть файл

@ -1,5 +1,12 @@
abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string
abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<string>
abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken
abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken>
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.AuthToken() -> void
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.AuthToken(string token, System.DateTimeOffset expiresOn) -> void
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.ExpiresOn.get -> System.DateTimeOffset
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.ExpiresOn.set -> void
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.Token.get -> string
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.Token.set -> void
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope
Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope
@ -7,4 +14,8 @@ Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetAzureToken
Microsoft.ApplicationInsights.Channel.IAsyncFlushable
Microsoft.ApplicationInsights.Channel.IAsyncFlushable.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<bool>
Microsoft.ApplicationInsights.Channel.InMemoryChannel.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<bool>
Microsoft.ApplicationInsights.TelemetryClient.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<bool>
Microsoft.ApplicationInsights.TelemetryClient.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<bool>
override Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.Equals(object obj) -> bool
override Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.GetHashCode() -> int
static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.operator !=(Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken left, Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken right) -> bool
static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken.operator ==(Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken left, Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.AuthToken right) -> bool

Просмотреть файл

@ -2,6 +2,8 @@
namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementation.Authentication
{
using System;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
@ -67,10 +69,12 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati
{
var mockCredential = new MockCredential();
var requestContext = new TokenRequestContext(new string[] { "test/scope" });
var tokenFromCredential = mockCredential.GetToken(requestContext, CancellationToken.None);
var testResult = ReflectionCredentialEnvelope.AzureCore.InvokeGetToken(mockCredential, requestContext, CancellationToken.None);
Assert.AreEqual("TEST TOKEN test/scope", testResult);
var tokenFromReflection = ReflectionCredentialEnvelope.AzureCore.InvokeGetToken(mockCredential, requestContext, CancellationToken.None);
Assert.AreEqual(tokenFromCredential.Token, tokenFromReflection.Token);
Assert.AreEqual(tokenFromCredential.ExpiresOn, tokenFromReflection.ExpiresOn);
}
[TestMethod]
@ -78,10 +82,12 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati
{
var mockCredential = new MockCredential();
var requestContext = new TokenRequestContext(new string[] { "test/scope" });
var tokenFromCredential = mockCredential.GetToken(requestContext, CancellationToken.None);
var testResult = await ReflectionCredentialEnvelope.AzureCore.InvokeGetTokenAsync(mockCredential, requestContext, CancellationToken.None);
var tokenFromReflection = await ReflectionCredentialEnvelope.AzureCore.InvokeGetTokenAsync(mockCredential, requestContext, CancellationToken.None);
Assert.AreEqual("TEST TOKEN test/scope", testResult);
Assert.AreEqual(tokenFromCredential.Token, tokenFromReflection.Token);
Assert.AreEqual(tokenFromCredential.ExpiresOn, tokenFromReflection.ExpiresOn);
}
/// <summary>
@ -90,12 +96,15 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati
[TestMethod]
public void VerifyGetToken_UsingDynamicTypes()
{
var mockCredential = (object)new MockCredential();
var requestContext = ReflectionCredentialEnvelope.AzureCore.MakeTokenRequestContext(new[] { "test/scope" });
var mockCredential = new MockCredential();
var requestContext = new TokenRequestContext(new string[] { "test/scope" });
var tokenFromCredential = mockCredential.GetToken(requestContext, CancellationToken.None);
var testResult = ReflectionCredentialEnvelope.AzureCore.InvokeGetToken(mockCredential, requestContext, CancellationToken.None);
Assert.AreEqual("TEST TOKEN test/scope", testResult);
var requestContextFromReflection = ReflectionCredentialEnvelope.AzureCore.MakeTokenRequestContext(new[] { "test/scope" });
var tokenFromReflection = ReflectionCredentialEnvelope.AzureCore.InvokeGetToken((object)mockCredential, requestContextFromReflection, CancellationToken.None);
Assert.AreEqual(tokenFromCredential.Token, tokenFromReflection.Token);
Assert.AreEqual(tokenFromCredential.ExpiresOn, tokenFromReflection.ExpiresOn);
}
/// <summary>
@ -104,12 +113,15 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati
[TestMethod]
public async Task VerifyGetTokenAsync_UsingDynamicTypes()
{
var mockCredential = (object)new MockCredential();
var requestContext = ReflectionCredentialEnvelope.AzureCore.MakeTokenRequestContext(new[] { "test/scope" });
var mockCredential = new MockCredential();
var requestContext = new TokenRequestContext(new string[] { "test/scope" });
var tokenFromCredential = mockCredential.GetToken(requestContext, CancellationToken.None);
var testResult = await ReflectionCredentialEnvelope.AzureCore.InvokeGetTokenAsync(mockCredential, requestContext, CancellationToken.None);
var requestContextFromReflection = ReflectionCredentialEnvelope.AzureCore.MakeTokenRequestContext(new[] { "test/scope" });
var tokenFromReflection = await ReflectionCredentialEnvelope.AzureCore.InvokeGetTokenAsync((object)mockCredential, requestContextFromReflection, CancellationToken.None);
Assert.AreEqual("TEST TOKEN test/scope", testResult);
Assert.AreEqual(tokenFromCredential.Token, tokenFromReflection.Token);
Assert.AreEqual(tokenFromCredential.ExpiresOn, tokenFromReflection.ExpiresOn);
}
/// <summary>
@ -120,12 +132,13 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati
{
var requestContext = new TokenRequestContext(scopes: AuthConstants.GetScopes());
var mockCredential = new MockCredential();
var tokenUsingTypes = mockCredential.GetToken(requestContext, CancellationToken.None);
var tokenFromCredential = mockCredential.GetToken(requestContext, CancellationToken.None);
var reflectionCredentialEnvelope = new ReflectionCredentialEnvelope(mockCredential);
var tokenUsingReflection = reflectionCredentialEnvelope.GetToken();
var tokenFromReflection = reflectionCredentialEnvelope.GetToken();
Assert.AreEqual(tokenUsingTypes.Token, tokenUsingReflection);
Assert.AreEqual(tokenFromCredential.Token, tokenFromReflection.Token);
Assert.AreEqual(tokenFromCredential.ExpiresOn, tokenFromReflection.ExpiresOn);
}
/// <summary>
@ -136,12 +149,13 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati
{
var requestContext = new TokenRequestContext(scopes: AuthConstants.GetScopes());
var mockCredential = new MockCredential();
var tokenUsingTypes = await mockCredential.GetTokenAsync(requestContext, CancellationToken.None);
var tokenFromCredential = await mockCredential.GetTokenAsync(requestContext, CancellationToken.None);
var reflectionCredentialEnvelope = new ReflectionCredentialEnvelope(mockCredential);
var tokenUsingReflection = await reflectionCredentialEnvelope.GetTokenAsync();
var tokenFromReflection = await reflectionCredentialEnvelope.GetTokenAsync();
Assert.AreEqual(tokenUsingTypes.Token, tokenUsingReflection);
Assert.AreEqual(tokenFromCredential.Token, tokenFromReflection.Token);
Assert.AreEqual(tokenFromCredential.ExpiresOn, tokenFromReflection.ExpiresOn);
}
[TestMethod]
@ -153,7 +167,7 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati
var reflectionCredentialEnvelope = new ReflectionCredentialEnvelope(mockCredential);
var token = reflectionCredentialEnvelope.GetToken();
Assert.IsNull(token);
Assert.AreEqual(default(AuthToken), token);
}
[TestMethod]
@ -165,11 +179,131 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati
var reflectionCredentialEnvelope = new ReflectionCredentialEnvelope(mockCredential);
var token = await reflectionCredentialEnvelope.GetTokenAsync();
Assert.IsNull(token);
Assert.AreEqual(default(AuthToken), token);
}
#region TestClasses
[TestMethod]
public void TestReflection()
{
Type typeTokenCredential = Type.GetType("Azure.Core.TokenCredential, Azure.Core");
Type typeTokenRequestContext = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core");
Type typeCancellationToken = typeof(CancellationToken);
var parameterExpression_tokenCredential = Expression.Parameter(type: typeTokenCredential, name: "parameterExpression_TokenCredential");
var parameterExpression_requestContext = Expression.Parameter(type: typeTokenRequestContext, name: "parameterExpression_RequestContext");
var parameterExpression_cancellationToken = Expression.Parameter(type: typeCancellationToken, name: "parameterExpression_CancellationToken");
var exprGetToken = Expression.Call(
instance: parameterExpression_tokenCredential,
method: typeTokenCredential.GetMethod(name: "GetToken", types: new Type[] { typeTokenRequestContext, typeCancellationToken }),
arg0: parameterExpression_requestContext,
arg1: parameterExpression_cancellationToken);
var exprTokenProperty = Expression.Property(
expression: exprGetToken,
propertyName: "Token");
var exprExpiresOnProperty = Expression.Property(
expression: exprGetToken,
propertyName: "ExpiresOn");
Type typeAuthToken = typeof(AuthToken);
ConstructorInfo authTokenCtor = typeAuthToken.GetConstructor(new Type[] { typeof(string), typeof(DateTimeOffset) });
var exprAuthTokenCtor = Expression.New(authTokenCtor, exprTokenProperty, exprExpiresOnProperty);
//Expression.init
var compiledExpression = Expression.Lambda(
//body: exprTokenProperty,
body: exprAuthTokenCtor,
parameters: new ParameterExpression[]
{
parameterExpression_tokenCredential,
parameterExpression_requestContext,
parameterExpression_cancellationToken,
}).Compile();
//----------------------------------
var mockCredential = new MockCredential();
var requestContext = new TokenRequestContext(new string[] { "test/scope" });
CancellationToken ct = default;
var test = (AuthToken)compiledExpression.DynamicInvoke(mockCredential, requestContext, ct);
}
[TestMethod]
public void TestReflection2()
{
Type typeTokenCredential = Type.GetType("Azure.Core.TokenCredential, Azure.Core");
Type typeTokenRequestContext = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core");
Type typeCancellationToken = typeof(CancellationToken);
var parameterExpression_tokenCredential = Expression.Parameter(type: typeTokenCredential, name: "parameterExpression_TokenCredential");
var parameterExpression_requestContext = Expression.Parameter(type: typeTokenRequestContext, name: "parameterExpression_RequestContext");
var parameterExpression_cancellationToken = Expression.Parameter(type: typeCancellationToken, name: "parameterExpression_CancellationToken");
var exprGetToken = Expression.Call(
instance: parameterExpression_tokenCredential,
method: typeTokenCredential.GetMethod(name: "GetToken", types: new Type[] { typeTokenRequestContext, typeCancellationToken }),
arg0: parameterExpression_requestContext,
arg1: parameterExpression_cancellationToken);
var compiledExpression1 = Expression.Lambda(
body: exprGetToken,
parameters: new ParameterExpression[]
{
parameterExpression_tokenCredential,
parameterExpression_requestContext,
parameterExpression_cancellationToken,
}).Compile();
// ------------------------------
var mockCredential = new MockCredential();
var requestContext = new TokenRequestContext(new string[] { "test/scope" });
CancellationToken ct = default;
var objAccessToken = compiledExpression1.DynamicInvoke(mockCredential, requestContext, ct);
// ----------------------------
Type typeAccessToken = Type.GetType("Azure.Core.AccessToken, Azure.Core");
var parameterExpression_AccessToken = Expression.Parameter(typeAccessToken, "parameterExpression_AccessToken");
var exprTokenProperty = Expression.Property(
expression: parameterExpression_AccessToken,
propertyName: "Token");
var exprExpiresOnProperty = Expression.Property(
expression: parameterExpression_AccessToken,
propertyName: "ExpiresOn");
Type typeAuthToken = typeof(AuthToken);
ConstructorInfo authTokenCtor = typeAuthToken.GetConstructor(new Type[] { typeof(string), typeof(DateTimeOffset) });
var exprAuthTokenCtor = Expression.New(authTokenCtor, exprTokenProperty, exprExpiresOnProperty);
var compiledExpression2 = Expression.Lambda(
//body: exprTokenProperty,
body: exprAuthTokenCtor,
parameters: new ParameterExpression[]
{
parameterExpression_AccessToken,
}).Compile();
//----------------------------------
var test = compiledExpression2.DynamicInvoke(objAccessToken);
}
#region TestClasses
/// <summary>
/// This class inherits <see cref="MockCredential"/> which inherits <see cref="Azure.Core.TokenCredential"/>.
/// This class is used to verify that the <see cref="ReflectionCredentialEnvelope"/> can correctly identify tests that inherit <see cref="Azure.Core.TokenCredential"/>.

Просмотреть файл

@ -59,9 +59,8 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati
[TestMethod]
public async Task VerifyTransmissionSendAsync_WithCredential_SetsAuthHeader()
{
var credendialEnvelope = new ReflectionCredentialEnvelope(new MockCredential());
var token = credendialEnvelope.GetToken();
var credentialEnvelope = new ReflectionCredentialEnvelope(new MockCredential());
var authToken = credentialEnvelope.GetToken();
var handler = new HandlerForFakeHttpClient
{
@ -70,7 +69,7 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati
{
// VALIDATE
Assert.AreEqual(AuthConstants.AuthorizationTokenPrefix.Trim(), req.Headers.Authorization.Scheme);
Assert.AreEqual(token, req.Headers.Authorization.Parameter);
Assert.AreEqual(authToken.Token, req.Headers.Authorization.Parameter);
return Task.FromResult<HttpResponseMessage>(new HttpResponseMessage());
}
@ -84,7 +83,7 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati
// Instantiate Transmission with the mock HttpClient
var transmission = new Transmission(testUri, new byte[] { 1, 2, 3, 4, 5 }, fakeHttpClient, expectedContentType, expectedContentEncoding);
transmission.CredentialEnvelope = credendialEnvelope;
transmission.CredentialEnvelope = credentialEnvelope;
var result = await transmission.SendAsync();
}

Просмотреть файл

@ -417,14 +417,14 @@
// TODO: NEED TO USE CACHING HERE
var authToken = this.CredentialEnvelope.GetToken();
if (authToken == null)
if (authToken == default(AuthToken))
{
// TODO: DO NOT SEND. RETURN FAILURE AND LET CHANNEL DECIDE WHEN TO RETRY.
// This could be either a configuration error or the AAD service is unavailable.
}
else
{
request.Headers.TryAddWithoutValidation(AuthConstants.AuthorizationHeaderName, AuthConstants.AuthorizationTokenPrefix + authToken);
request.Headers.TryAddWithoutValidation(AuthConstants.AuthorizationHeaderName, AuthConstants.AuthorizationTokenPrefix + authToken.Token);
}
}

Просмотреть файл

@ -0,0 +1,62 @@
namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication
{
using System;
/// <summary>
/// This represents the Azure.Core.AccessToken returned by Azure.Core.TokenCredential.
/// (https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/core/Azure.Core/src/AccessToken.cs).
/// </summary>
public struct AuthToken
{
/// <summary>
/// Initializes a new instance of <see cref="AuthToken"/>.
/// </summary>
/// <param name="token">Access token.</param>
/// <param name="expiresOn">DateTimeOffset representing when the access token expires.</param>
public AuthToken(string token, DateTimeOffset expiresOn)
{
this.Token = token;
this.ExpiresOn = expiresOn;
}
/// <summary>
/// Gets or sets get the access token value.
/// </summary>
public string Token { get; set; }
/// <summary>
/// Gets or sets the time when the provided token expires.
/// </summary>
public DateTimeOffset ExpiresOn { get; set; }
/// <summary>
/// Determine if two instance of AuthToken are equal.
/// </summary>
/// <param name="left">An instance of AuthToken on the left side of the operator.</param>
/// <param name="right">An instance of AuthToken on the right side of the operator.</param>
/// <returns>Returns a boolean indicating if the params are equal.</returns>
public static bool operator ==(AuthToken left, AuthToken right) => left.Equals(right);
/// <summary>
/// Determine if two instance of AuthToken are not equal.
/// </summary>
/// <param name="left">An instance of AuthToken on the left side of the operator.</param>
/// <param name="right">An instance of AuthToken on the right side of the operator.</param>
/// <returns>Returns a boolean indicating if the params are not equal.</returns>
public static bool operator !=(AuthToken left, AuthToken right) => !left.Equals(right);
/// <inheritdoc />
public override bool Equals(object obj)
{
if (obj is AuthToken authToken)
{
return authToken.ExpiresOn == this.ExpiresOn && authToken.Token == this.Token;
}
return false;
}
/// <inheritdoc />
public override int GetHashCode() => this.Token.GetHashCode() ^ this.ExpiresOn.GetHashCode();
}
}

Просмотреть файл

@ -5,6 +5,7 @@
/// <summary>
/// This interface defines a class that can interact with Azure.Core.TokenCredential.
/// See also: (https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/core/Azure.Core/src/TokenCredential.cs).
/// </summary>
public abstract class CredentialEnvelope
{
@ -21,7 +22,7 @@
/// </remarks>
/// <param name="cancellationToken">The System.Threading.CancellationToken to use.</param>
/// <returns>A valid Azure.Core.AccessToken.</returns>
public abstract string GetToken(CancellationToken cancellationToken = default);
public abstract AuthToken GetToken(CancellationToken cancellationToken = default);
/// <summary>
/// Gets an Azure.Core.AccessToken.
@ -31,6 +32,6 @@
/// </remarks>
/// <param name="cancellationToken">The System.Threading.CancellationToken to use.</param>
/// <returns>A valid Azure.Core.AccessToken.</returns>
public abstract Task<string> GetTokenAsync(CancellationToken cancellationToken = default);
public abstract Task<AuthToken> GetTokenAsync(CancellationToken cancellationToken = default);
}
}

Просмотреть файл

@ -3,6 +3,7 @@
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
@ -52,7 +53,7 @@
/// </remarks>
/// <param name="cancellationToken">The System.Threading.CancellationToken to use.</param>
/// <returns>A valid Azure.Core.AccessToken.</returns>
public override string GetToken(CancellationToken cancellationToken = default)
public override AuthToken GetToken(CancellationToken cancellationToken = default)
{
try
{
@ -61,7 +62,7 @@
catch (Exception ex)
{
CoreEventSource.Log.FailedToGetToken(ex.ToInvariantString());
return null;
return default;
}
}
@ -73,7 +74,7 @@
/// </remarks>
/// <param name="cancellationToken">The System.Threading.CancellationToken to use.</param>
/// <returns>A valid Azure.Core.AccessToken.</returns>
public override async Task<string> GetTokenAsync(CancellationToken cancellationToken = default)
public override async Task<AuthToken> GetTokenAsync(CancellationToken cancellationToken = default)
{
try
{
@ -82,7 +83,7 @@
catch (Exception ex)
{
CoreEventSource.Log.FailedToGetToken(ex.ToInvariantString());
return null;
return default;
}
}
@ -140,30 +141,24 @@
/// </summary>
internal static class AzureCore
{
private static readonly Delegate GetTokenValue;
private static readonly Delegate GetTokenAsyncValue;
private static readonly Delegate GetTokenProperty;
private static readonly Delegate GetTokenValue = BuildDelegateGetToken();
private static readonly Delegate GetTokenAsyncAsTask = BuildDelegateGetTokenAsync();
private static readonly Delegate GetTaskResult = BuildGetTaskResult();
private static readonly Delegate AccessTokenToAuthToken = BuildDelegateAccessTokenToAuthToken();
[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1810:Initialize reference type static fields inline", Justification = "For both optimization and readability, I'm building these objects in the same method.")]
static AzureCore()
internal static AuthToken InvokeGetToken(object tokenCredential, object tokenRequestContext, CancellationToken cancellationToken)
{
GetTokenValue = BuildDelegateGetToken();
var asyncDelegates = BuildDelegateGetTokenAsync();
GetTokenAsyncValue = asyncDelegates[0];
GetTokenProperty = asyncDelegates[1];
var objAccessToken = GetTokenValue.DynamicInvoke(tokenCredential, tokenRequestContext, cancellationToken);
return (AuthToken)AccessTokenToAuthToken.DynamicInvoke(objAccessToken);
}
internal static string InvokeGetToken(object tokenCredential, object tokenRequestContext, CancellationToken cancellationToken)
internal static async Task<AuthToken> InvokeGetTokenAsync(object tokenCredential, object tokenRequestContext, CancellationToken cancellationToken)
{
return (string)GetTokenValue.DynamicInvoke(tokenCredential, tokenRequestContext, cancellationToken);
}
internal static async Task<string> InvokeGetTokenAsync(object tokenCredential, object tokenRequestContext, CancellationToken cancellationToken)
{
var task = (Task)GetTokenAsyncValue.DynamicInvoke(tokenCredential, tokenRequestContext, cancellationToken);
var task = (Task)GetTokenAsyncAsTask.DynamicInvoke(tokenCredential, tokenRequestContext, cancellationToken);
await task.ConfigureAwait(false);
return (string)GetTokenProperty.DynamicInvoke(task);
var objAccessToken = GetTaskResult.DynamicInvoke(task);
return (AuthToken)AccessTokenToAuthToken.DynamicInvoke(objAccessToken);
}
/// <summary>
@ -178,9 +173,49 @@
args: new object[] { scopes, null, });
}
/// <summary>
/// This is a wrapper for Azure.Core.AccessToken:
/// <code>public struct AccessToken</code>
/// (https://docs.microsoft.com/dotnet/api/azure.core.accesstoken).
/// </summary>
/// <returns>
/// Returns a delegate that receives an Azure.Core.AccessToken and emits an <see cref="AuthToken"/>.
/// </returns>
private static Delegate BuildDelegateAccessTokenToAuthToken()
{
Type typeAccessToken = Type.GetType("Azure.Core.AccessToken, Azure.Core");
var parameterExpression_AccessToken = Expression.Parameter(typeAccessToken, "parameterExpression_AccessToken");
var exprTokenProperty = Expression.Property(
expression: parameterExpression_AccessToken,
propertyName: "Token");
var exprExpiresOnProperty = Expression.Property(
expression: parameterExpression_AccessToken,
propertyName: "ExpiresOn");
Type typeAuthToken = typeof(AuthToken);
ConstructorInfo authTokenCtor = typeAuthToken.GetConstructor(new Type[] { typeof(string), typeof(DateTimeOffset) });
var exprAuthTokenCtor = Expression.New(authTokenCtor, exprTokenProperty, exprExpiresOnProperty);
return Expression.Lambda(
body: exprAuthTokenCtor,
parameters: new ParameterExpression[]
{
parameterExpression_AccessToken,
}).Compile();
}
/// <summary>
/// This creates a wrapper for the following method:
/// <code>public abstract Azure.Core.AccessToken GetToken (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken).</code>
/// (https://docs.microsoft.com/dotnet/api/azure.core.tokencredential.gettoken).
/// </summary>
/// <returns>
/// Returns a delegate that receives an Azure.Core.TokenCredential and emits an Azure.Core.AccessToken.
/// </returns>
private static Delegate BuildDelegateGetToken()
{
Type typeTokenCredential = Type.GetType("Azure.Core.TokenCredential, Azure.Core");
@ -197,12 +232,8 @@
arg0: parameterExpression_requestContext,
arg1: parameterExpression_cancellationToken);
var exprTokenProperty = Expression.Property(
expression: exprGetToken,
propertyName: "Token");
return Expression.Lambda(
body: exprTokenProperty,
body: exprGetToken,
parameters: new ParameterExpression[]
{
parameterExpression_tokenCredential,
@ -217,17 +248,12 @@
/// (https://docs.microsoft.com/dotnet/api/azure.core.tokencredential.gettokenasync).
/// </summary>
/// <returns>
/// The Expression Tree library cannot handle async methods.
/// As a workaround, this method returns two Delegates.
/// First;
/// The first Delegate is a wrapper around GetTokenAsync which returns a ValueTask of AccessToken.
/// Then calls ValueTask.GetTask to convert that to a Task which is a known type for older frameworks.
/// This Task can be awaited.
/// Second;
/// The second Delegate is a wrapper around Task.Result which returns the AccessToken.
/// Then calls AccessToken.Token to get the string token.
/// Returns a delegate that is a wrapper around GetTokenAsync which returns a System.Threading.Tasks.ValueTask of Azure.Core.AccessToken.
/// Then converts that System.Threading.Tasks.ValueTask to <see cref="Task"/> which can be awaited.
/// NOTE: The Expression Tree library cannot handle async methods.
/// NOTE: ValueTask is not recognized by older versions of .NET Framework.
/// </returns>
private static Delegate[] BuildDelegateGetTokenAsync()
private static Delegate BuildDelegateGetTokenAsync()
{
Type typeTokenCredential = Type.GetType("Azure.Core.TokenCredential, Azure.Core");
Type typeTokenRequestContext = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core");
@ -237,7 +263,6 @@
var parameterExpression_RequestContext = Expression.Parameter(type: typeTokenRequestContext, name: "parameterExpression_RequestContext");
var parameterExpression_CancellationToken = Expression.Parameter(type: typeCancellationToken, name: "parameterExpression_CancellationToken");
// public abstract System.Threading.Tasks.ValueTask<Azure.Core.AccessToken> GetTokenAsync (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken);
var methodInfo_GetTokenAsync = typeTokenCredential.GetMethod(name: "GetTokenAsync", types: new Type[] { typeTokenRequestContext, typeCancellationToken });
var exprGetTokenAsync = Expression.Call(
@ -252,7 +277,7 @@
instance: exprGetTokenAsync,
method: methodInfo_AsTask);
var delegateGetTokenAsync = Expression.Lambda(
return Expression.Lambda(
body: exprAsTask,
parameters: new ParameterExpression[]
{
@ -260,25 +285,36 @@
parameterExpression_RequestContext,
parameterExpression_CancellationToken,
}).Compile();
}
/// <summary>
/// This is a wrapper for a <see cref="Task"/> that came from Azure.Core.AccessToken.GetTokenAsync.
/// <code>public abstract System.Threading.Tasks.ValueTask&lt;Azure.Core.AccessToken> GetTokenAsync (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken);</code>
/// (https://docs.microsoft.com/dotnet/api/azure.core.tokencredential.gettokenasync).
/// </summary>
/// <returns>
/// Returns a delegate which receives a <see cref="Task"/> and emits an Azure.Core.AccessToken.
/// </returns>
private static Delegate BuildGetTaskResult()
{
Type typeTokenCredential = Type.GetType("Azure.Core.TokenCredential, Azure.Core");
Type typeTokenRequestContext = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core");
Type typeCancellationToken = typeof(CancellationToken);
var methodInfo_GetTokenAsync = typeTokenCredential.GetMethod(name: "GetTokenAsync", types: new Type[] { typeTokenRequestContext, typeCancellationToken });
var methodInfo_AsTask = methodInfo_GetTokenAsync.ReturnType.GetMethod("AsTask");
var parameterExpression_Task = Expression.Parameter(type: methodInfo_AsTask.ReturnType, name: "parameterExpression_Task");
var exprResultProperty = Expression.Property(
expression: parameterExpression_Task,
propertyName: "Result");
var exprTokenProperty = Expression.Property(
expression: exprResultProperty,
propertyName: "Token");
var delegateTokenProperty = Expression.Lambda(
body: exprTokenProperty,
return Expression.Lambda(
body: exprResultProperty,
parameters: new ParameterExpression[]
{
parameterExpression_Task,
}).Compile();
return new[] { delegateGetTokenAsync, delegateTokenProperty };
}
}
}

Просмотреть файл

@ -7,6 +7,7 @@
using System.Threading.Tasks;
using Microsoft.ApplicationInsights.Extensibility.Filtering;
using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication;
using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing;
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.QuickPulse.Helpers;
@ -107,11 +108,11 @@
this.firstStateUpdate = false;
}
string authToken = null;
AuthToken authToken = default;
if (this.telemetryConfiguration.CredentialEnvelope != null)
{
authToken = this.telemetryConfiguration.CredentialEnvelope.GetToken();
if (authToken == null)
if (authToken == default)
{
// If a credential has been set on the configuration and we fail to get a token, do net send.
QuickPulseEventSource.Log.FailedToGetAuthToken();
@ -150,7 +151,7 @@
instrumentationKey,
this.currentConfigurationETag,
authApiKey,
authToken,
authToken.Token,
out configurationInfo,
this.collectionConfigurationErrors.ToArray());
@ -185,7 +186,7 @@
this.timeProvider.UtcNow,
this.currentConfigurationETag,
authApiKey,
authToken,
authToken.Token,
out configurationInfo,
out TimeSpan? servicePollingIntervalHint);