22// Licensed under the MIT License.
33
44using System . Diagnostics ;
5+ using System . Diagnostics . Tracing ;
56using System . Net . Http . Json ;
67using System . Text ;
78using System . Text . Json ;
89using System . Text . RegularExpressions ;
910using Azure . Core ;
11+ using Azure . Core . Diagnostics ;
1012using Azure . Identity ;
1113using Microsoft . DevProxy . Abstractions ;
1214using Microsoft . DevProxy . Plugins . RequestLogs . ApiCenter ;
@@ -24,19 +26,15 @@ internal class ApiCenterOnboardingPluginConfiguration
2426 public string ServiceName { get ; set ; } = "" ;
2527 public string WorkspaceName { get ; set ; } = "default" ;
2628 public bool CreateApicEntryForNewApis { get ; set ; } = true ;
29+ public bool ExcludeDevCredentials { get ; set ; } = false ;
30+ public bool ExcludeProdCredentials { get ; set ; } = true ;
2731}
2832
2933public class ApiCenterOnboardingPlugin : BaseProxyPlugin
3034{
3135 private ApiCenterOnboardingPluginConfiguration _configuration = new ( ) ;
3236 private readonly string [ ] _scopes = [ "https://management.azure.com/.default" ] ;
33- private readonly TokenCredential _credential = new ChainedTokenCredential (
34- new VisualStudioCredential ( ) ,
35- new VisualStudioCodeCredential ( ) ,
36- new AzureCliCredential ( ) ,
37- new AzurePowerShellCredential ( ) ,
38- new AzureDeveloperCliCredential ( )
39- ) ;
37+ private TokenCredential _credential = new DefaultAzureCredential ( ) ;
4038 private HttpClient ? _httpClient ;
4139 private JsonSerializerOptions _jsonSerializerOptions = new JsonSerializerOptions
4240 {
@@ -57,29 +55,63 @@ public override void Register(IPluginEvents pluginEvents,
5755
5856 if ( string . IsNullOrEmpty ( _configuration . SubscriptionId ) )
5957 {
60- _logger ? . LogError ( "Specify SubscriptionId in the ApiCenterOnboardingPlugin configuration. The ApiCenterOnboardingPlugin will not be used." ) ;
58+ _logger ? . LogError ( "Specify SubscriptionId in the {plugin} configuration. The {plugin} will not be used." , Name , Name ) ;
6159 return ;
6260 }
6361 if ( string . IsNullOrEmpty ( _configuration . ResourceGroupName ) )
6462 {
65- _logger ? . LogError ( "Specify ResourceGroupName in the ApiCenterOnboardingPlugin configuration. The ApiCenterOnboardingPlugin will not be used." ) ;
63+ _logger ? . LogError ( "Specify ResourceGroupName in the {plugin} configuration. The {plugin} will not be used." , Name , Name ) ;
6664 return ;
6765 }
6866 if ( string . IsNullOrEmpty ( _configuration . ServiceName ) )
6967 {
70- _logger ? . LogError ( "Specify ServiceName in the ApiCenterOnboardingPlugin configuration. The ApiCenterOnboardingPlugin will not be used." ) ;
68+ _logger ? . LogError ( "Specify ServiceName in the {plugin} configuration. The {plugin} will not be used." , Name , Name ) ;
7169 return ;
7270 }
71+ if ( _configuration . ExcludeDevCredentials && _configuration . ExcludeProdCredentials )
72+ {
73+ _logger ? . LogError ( "Both ExcludeDevCredentials and ExcludeProdCredentials are set to true. You need to use at least one set of credentials The {plugin} will not be used." , Name ) ;
74+ return ;
75+ }
76+
77+ var credentials = new List < TokenCredential > ( ) ;
78+ if ( ! _configuration . ExcludeDevCredentials )
79+ {
80+ credentials . AddRange ( [
81+ new SharedTokenCacheCredential ( ) ,
82+ new VisualStudioCredential ( ) ,
83+ new VisualStudioCodeCredential ( ) ,
84+ new AzureCliCredential ( ) ,
85+ new AzurePowerShellCredential ( ) ,
86+ new AzureDeveloperCliCredential ( ) ,
87+ ] ) ;
88+ }
89+ if ( ! _configuration . ExcludeProdCredentials )
90+ {
91+ credentials . AddRange ( [
92+ new EnvironmentCredential ( ) ,
93+ new WorkloadIdentityCredential ( ) ,
94+ new ManagedIdentityCredential ( )
95+ ] ) ;
96+ }
97+ _credential = new ChainedTokenCredential ( credentials . ToArray ( ) ) ;
98+
99+ if ( _logger ? . LogLevel == LogLevel . Debug )
100+ {
101+ var consoleListener = AzureEventSourceListener . CreateConsoleLogger ( EventLevel . Verbose ) ;
102+ }
73103
104+ _logger ? . LogDebug ( "[{now}] Plugin {plugin} checking Azure auth..." , DateTime . Now , Name ) ;
74105 try
75106 {
76107 _ = _credential . GetTokenAsync ( new TokenRequestContext ( _scopes ) , CancellationToken . None ) . Result ;
77108 }
78109 catch ( AuthenticationFailedException ex )
79110 {
80- _logger ? . LogError ( ex , "Failed to authenticate with Azure. The ApiCenterOnboardingPlugin will not be used." ) ;
111+ _logger ? . LogError ( ex , "Failed to authenticate with Azure. The {plugin} will not be used." , Name ) ;
81112 return ;
82113 }
114+ _logger ? . LogDebug ( "[{now}] Plugin {plugin} auth confirmed..." , DateTime . Now , Name ) ;
83115
84116 var authenticationHandler = new AuthenticationDelegatingHandler ( _credential , _scopes )
85117 {
@@ -114,7 +146,8 @@ private async Task AfterRecordingStop(object sender, RecordingArgs e)
114146 var newApis = new List < Tuple < string , string > > ( ) ;
115147 var interceptedRequests = e . RequestLogs
116148 . Where ( l => l . MessageType == MessageType . InterceptedRequest )
117- . Select ( request => {
149+ . Select ( request =>
150+ {
118151 var methodAndUrl = request . MessageLines . First ( ) . Split ( ' ' ) ;
119152 return new Tuple < string , string > ( methodAndUrl [ 0 ] , methodAndUrl [ 1 ] ) ;
120153 } )
0 commit comments