尝试使用其SDK针对Azure Management API进行身份验证。我可以使用户通过MSAL.NET SDK进行身份验证。但是,当我尝试将Bearer令牌传递给ClientCrendentials时,我可以和AuthorizationFailed消息一起使用。
我已在Active Directory实例中启用user_impersination
并委派权限,并通过应用程序门户注册了我的应用程序。
租户设置为common
class Program
{
static readonly string TenantID = ConfigurationManager.AppSettings.Get("tenant_id");
static readonly string ClientID = ConfigurationManager.AppSettings.Get("client_id");
static readonly string Scopes = ConfigurationManager.AppSettings.Get("scopes");
static AuthenticationResult Authentication { get; set; }
static AzureEnvironment AzureEnvironment => AzureEnvironment.AzureGlobalCloud;
static void Main(string[] args)
{
// useful links
// Micorosft.Identity.Client https://github.com/AzureAD/microsoft-authentication-library-for-dotnet
DoLoginAsync().Wait();
CallAzure().Wait();
//CallMsGraphAPI().Wait();
Console.Read();
}
static async Task DoLoginAsync()
{
try
{
IPublicClientApplication client = PublicClientApplicationBuilder.Create(ClientID)
.WithAuthority(AzureCloudInstance.AzurePublic, TenantID)
.Build();
Authentication = await client.AcquireTokenInteractive(Scopes.Split(','))
.ExecuteAsync();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
static async Task CallAzure()
{
try
{
var client = RestClient.Configure()
.WithEnvironment(AzureEnvironment)
.WithCredentials(GetCredentials())
.WithLogLevel(HttpLoggingDelegatingHandler.Level.BodyAndHeaders)
.Build();
var subscriptionClient = new SubscriptionClient(client);
var subscriptions = await subscriptionClient.Subscriptions.ListAsync();
Console.WriteLine(subscriptions); // fails
}
catch(Exception ex)
{
Console.WriteLine(ex);
}
}
static AzureCredentials GetCredentials()
{
var provider = new StringTokenProvider(Authentication.AccessToken, "Bearer");
var tokenCredentials = new TokenCredentials(provider, TenantID, Authentication.Account.Username);
return new AzureCredentials(tokenCredentials, tokenCredentials, TenantID, AzureEnvironment);
}
}
我认为可以使用我在GetCredentials
方法中返回的承载令牌来授权用户。
答案 0 :(得分:0)
我设法解决了这个问题,有两点值得指出
Audience
是帐户TenantId
。如果不确定其工作原理,可以在Microsoft官方页面上详细了解它。scopes
的参数似乎支持多个范围,但实际上不支持。传递多个scope
会导致发生错误有用的资源
Best practices for ConfigureAwait
class Program
{
static AuthenticationResult AuthenticationResult { get; set; }
static readonly string ClientId = ConfigurationManager.AppSettings.Get("ClientId") ?? throw new ApplicationException("No ClientID configured in <appsettings /> App.Config");
static readonly IEnumerable<string> Scopes = new[] { "https://management.azure.com/user_impersonation" };
static IPublicClientApplication App { get; set; }
static void Main(string[] args)
{
App = PublicClientApplicationBuilder.Create(ClientId)
.WithLogging((level, message, containsPii) =>
{
Console.WriteLine("Error when using Public Client");
Console.WriteLine($"{level}: {message}");
}, LogLevel.Verbose, true, true)
.WithAuthority(AzureCloudInstance.AzurePublic, AadAuthorityAudience.AzureAdMultipleOrgs, true)
.Build();
DoLoginAsync().Wait();
CallAzureMangementRestApiAsync().Wait();
}
static async Task DoLoginAsync()
{
try
{
var accounts = await App.GetAccountsAsync().ConfigureAwait(false);
try
{
AuthenticationResult = await App.AcquireTokenSilent(Scopes, accounts.FirstOrDefault())
.ExecuteAsync()
.ConfigureAwait(false);
}
catch (MsalUiRequiredException)
{
AuthenticationResult = await App.AcquireTokenInteractive(Scopes)
.ExecuteAsync()
.ConfigureAwait(false);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
static async Task CallAzureMangementRestApiAsync()
{
try
{
try
{
var accounts = await App.GetAccountsAsync().ConfigureAwait(false);
AuthenticationResult = await App.AcquireTokenSilent(Scopes, accounts.FirstOrDefault())
.WithAuthority(AzureCloudInstance.AzurePublic, AuthenticationResult.TenantId)
.ExecuteAsync()
.ConfigureAwait(false);
}
catch (MsalUiRequiredException)
{
// UI needs to have the user call in
AuthenticationResult = await App.AcquireTokenInteractive(Scopes)
.WithAuthority(AzureCloudInstance.AzurePublic, AuthenticationResult.TenantId)
.ExecuteAsync()
.ConfigureAwait(false);
}
var client = RestClient.Configure()
.WithEnvironment(AzureEnvironment.FromName(AuthenticationResult?.Account?.Environment) ?? AzureEnvironment.AzureGlobalCloud)
.WithCredentials(GetAzureCredentials())
.WithLogLevel(HttpLoggingDelegatingHandler.Level.BodyAndHeaders)
.Build();
using (var subscriptionClient = new SubscriptionClient(client))
{
var subscriptions = await subscriptionClient.Subscriptions
.ListAsync()
.ConfigureAwait(false);
foreach (var s in subscriptions)
{
Console.WriteLine($"Id={s.Id};subscriptionId={s.SubscriptionId};displayName={s.DisplayName}");
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
static AzureCredentials GetAzureCredentials()
{
var provider = new StringTokenProvider(AuthenticationResult.AccessToken, "Bearer");
var token = new TokenCredentials(provider, AuthenticationResult.TenantId, AuthenticationResult.IdToken != null ? AuthenticationResult.UniqueId : AuthenticationResult.IdToken);
return new AzureCredentials(token, token, AuthenticationResult.TenantId, AzureEnvironment.AzureGlobalCloud);
}
}