【问题标题】:Authenticating Against Azure Magment API SDK with MSAL.NET使用 MSAL.NET 针对 Azure Magment API SDK 进行身份验证
【发布时间】:2019-06-27 17:27:38
【问题描述】:

尝试使用他们的SDK 对 Azure 管理 API 进行身份验证。我可以让用户通过 MSAL.NET SDK 进行身份验证。但是当我尝试传递 ClientCrendentials 的 Bearer 令牌时,我可以传递 AuthorizationFailed 消息。

我已启用user_impersination 并在我的 Active Directory 实例中委派权限,并通过应用程序门户注册我的应用程序。

租户设置为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 方法中返回的不记名令牌来授权用户。

【问题讨论】:

    标签: .net msal azure-management-api


    【解决方案1】:

    我设法解决了这个问题,有两点值得指出

    1. Audience 是帐户 TenantId。如果您不确定这是如何工作的,可以在 Microsoft 官方页面上了解更多信息。
    2. scopes 参数看起来像是支持多个作用域,但实际上并不支持。传递多个scope 会导致发生错误

    有用的资源

    • single to multi tenant applications
    • application audiences
    • choosing an authentication provider
    • 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);
          }
      }
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-14
      • 1970-01-01
      • 2017-04-08
      • 2019-07-09
      • 1970-01-01
      • 2015-08-09
      • 1970-01-01
      相关资源
      最近更新 更多