-
Notifications
You must be signed in to change notification settings - Fork 271
Expand file tree
/
Copy pathManagedIdentityClientAssertion.cs
More file actions
141 lines (127 loc) · 5.62 KB
/
Copy pathManagedIdentityClientAssertion.cs
File metadata and controls
141 lines (127 loc) · 5.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Identity.Client;
using Microsoft.Identity.Client.AppConfig;
using Microsoft.Identity.Client.Extensibility;
using Microsoft.Identity.Web.Certificateless;
namespace Microsoft.Identity.Web
{
/// <summary>
/// See https://aka.ms/ms-id-web/certificateless.
/// </summary>
public class ManagedIdentityClientAssertion : ClientAssertionProviderBase
{
IManagedIdentityApplication _managedIdentityApplication;
private readonly string _tokenExchangeUrl;
private readonly ILogger? _logger;
/// <summary>
/// See https://aka.ms/ms-id-web/certificateless.
/// </summary>
/// <param name="managedIdentityClientId">Optional ClientId of the Managed Identity</param>
public ManagedIdentityClientAssertion(string? managedIdentityClientId) :
this(managedIdentityClientId, tokenExchangeUrl: null, logger: null)
{
}
/// <summary>
/// See https://aka.ms/ms-id-web/certificateless.
/// </summary>
/// <param name="managedIdentityClientId">Optional ClientId of the Managed Identity</param>
/// <param name="tokenExchangeUrl">Optional audience of the token to be requested from Managed Identity. Default value is "api://AzureADTokenExchange".
/// This value is different on clouds other than Azure Public</param>
public ManagedIdentityClientAssertion(string? managedIdentityClientId, string? tokenExchangeUrl) :
this(managedIdentityClientId, tokenExchangeUrl, null)
{
}
/// <summary>
/// See https://aka.ms/ms-id-web/certificateless.
/// </summary>
/// <param name="managedIdentityClientId">Optional ClientId of the Managed Identity</param>
/// <param name="tokenExchangeUrl">Optional audience of the token to be requested from Managed Identity. Default value is "api://AzureADTokenExchange".
/// This value is different on clouds other than Azure Public</param>
/// <param name="logger">A logger</param>
public ManagedIdentityClientAssertion(string? managedIdentityClientId, string? tokenExchangeUrl, ILogger? logger)
{
_tokenExchangeUrl = tokenExchangeUrl ?? CertificatelessConstants.DefaultTokenExchangeUrl;
_logger = logger;
var id = ManagedIdentityId.SystemAssigned;
if (!string.IsNullOrEmpty(managedIdentityClientId))
{
id = ManagedIdentityId.WithUserAssignedClientId(managedIdentityClientId);
}
var builder = ManagedIdentityApplicationBuilder.Create(id);
if (_logger != null)
{
builder = builder.WithLogging(Log, ConvertMicrosoftExtensionsLogLevelToMsal(_logger), enablePiiLogging: false);
_logger.LogInformation($"ManagedIdentityClientAssertion with tokenExchangeUrl={_tokenExchangeUrl}");
}
_managedIdentityApplication = builder
.Build();
}
/// <summary>
/// Prototype of certificate-less authentication using a signed assertion
/// acquired with managed identity (certificateless).
/// </summary>
/// <returns>The signed assertion.</returns>
protected override async Task<ClientAssertion> GetClientAssertionAsync(AssertionRequestOptions? assertionRequestOptions)
{
var result = await _managedIdentityApplication
.AcquireTokenForManagedIdentity(_tokenExchangeUrl)
.ExecuteAsync(assertionRequestOptions?.CancellationToken ?? CancellationToken.None)
.ConfigureAwait(false);
return new ClientAssertion(result.AccessToken, result.ExpiresOn);
}
private void Log(
Client.LogLevel level,
string message,
bool containsPii)
{
switch (level)
{
case Client.LogLevel.Always:
_logger.LogInformation(message);
break;
case Client.LogLevel.Error:
_logger.LogError(message);
break;
case Client.LogLevel.Warning:
_logger.LogWarning(message);
break;
case Client.LogLevel.Info:
_logger.LogInformation(message);
break;
case Client.LogLevel.Verbose:
_logger.LogDebug(message);
break;
}
}
private Client.LogLevel? ConvertMicrosoftExtensionsLogLevelToMsal(ILogger logger)
{
if (logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)
|| logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Trace))
{
return Client.LogLevel.Verbose;
}
else if (logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Information))
{
return Client.LogLevel.Info;
}
else if (logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Warning))
{
return Client.LogLevel.Warning;
}
else if (logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Error)
|| logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Critical))
{
return Client.LogLevel.Error;
}
else
{
return null;
}
}
}
}