我正在尝试使用C#以编程方式从Microsoft.Azure.Management.Compute
检索托管服务。这需要ServiceClientCredential
,我不知道如何获得它。谁能帮帮我吗?我可以使用Microsoft.WindowsAzure.Management.Compute
来获取它们,但这里只返回ResourceManager下的实例而不是经典实例。
答案 0 :(得分:13)
首先,您需要创建Active Directory应用程序。使用此链接创建AD应用{{3}}
示例代码使用Microsoft.Azure.Management.Compute 13.0.1-prerelease SDK 网址:https://azure.microsoft.com/en-us/documentation/articles/resource-group-create-service-principal-portal/
public class CustomLoginCredentials : ServiceClientCredentials
{
private string AuthenticationToken { get; set; }
public override void InitializeServiceClient<T>(ServiceClient<T> client)
{
var authenticationContext =
new AuthenticationContext("https://login.windows.net/{tenantID}");
var credential = new ClientCredential(clientId: "xxxxx-xxxx-xx-xxxx-xxx", clientSecret: "{clientSecret}");
var result = authenticationContext.AcquireToken(resource: "https://management.core.windows.net/",
clientCredential: credential);
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the JWT token");
}
AuthenticationToken = result.AccessToken;
}
public override async Task ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request == null)
{
throw new ArgumentNullException("request");
}
if (AuthenticationToken == null)
{
throw new InvalidOperationException("Token Provider Cannot Be Null");
}
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AuthenticationToken);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//request.Version = new Version(apiVersion);
await base.ProcessHttpRequestAsync(request, cancellationToken);
}
}
以下是如何初始化客户端
netClient = new Microsoft.Azure.Management.Compute.ComputeManagementClient(new CustomLoginCredentials());
netClient.SubscriptionId = _subscriptionId;
答案 1 :(得分:2)
在游戏后期,但这就是我们在项目中执行此操作的方式。我们使用 .net 框架提供的令牌凭据来访问托管身份、visual studio(代码)身份或交互式身份。并连接到 azure 基础架构 API。
internal class CustomTokenProvider : ServiceClientCredentials
{
private const string BearerTokenType = "Bearer";
private TokenCredential _tokenCredential;
private readonly string[] _scopes;
private readonly IMemoryCache _cache;
public CustomTokenProvider(TokenCredential tokenCredential, string[] scopes, IMemoryCache cache)
{
_tokenCredential = tokenCredential ?? throw new ArgumentNullException(nameof(tokenCredential));
_scopes = scopes ?? throw new ArgumentNullException(nameof(scopes));
_cache = cache;
}
public override async Task ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request == null)
{
throw new ArgumentNullException(nameof(request));
}
var token = await _cache.GetOrCreateAsync("accessToken-tokenProvider." + string.Join("#", _scopes), async e =>
{
var accessToken = await _tokenCredential.GetTokenAsync(new TokenRequestContext(_scopes), cancellationToken);
e.AbsoluteExpiration = accessToken.ExpiresOn;
return accessToken.Token;
});
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(BearerTokenType, token);
await base.ProcessHttpRequestAsync(request, cancellationToken).ConfigureAwait(false);
}
}
几点说明:
答案 2 :(得分:0)
您现在要执行的操作是使用ITokenProvider和Microsoft.Rest.TokenCredentials。
try:
return BatchLog.objects.filter(batch_id=self.kwargs["pk"])[0]
except IndexError:
raise Http404('No logs for this id')
然后在您的DI配置中
public class CustomTokenProvider : ITokenProvider
{
private readonly CustomConfiguration _config;
public CustomTokenProvider(CustomConfiguration config)
{
_config = config;
}
public async Task<AuthenticationHeaderValue> GetAuthenticationHeaderAsync(CancellationToken cancellationToken)
{
// For app only authentication, we need the specific tenant id in the authority url
var tenantSpecificUrl = $"https://login.microsoftonline.com/{_config.TenantId}/";
// Create a confidential client to authorize the app with the AAD app
IConfidentialClientApplication clientApp = ConfidentialClientApplicationBuilder
.Create(_config.ClientId)
.WithClientSecret(_config.ClientSecret)
.WithAuthority(tenantSpecificUrl)
.Build();
// Make a client call if Access token is not available in cache
var authenticationResult = await clientApp
.AcquireTokenForClient(new List<string> { _config.Scope })
.ExecuteAsync();
return new AuthenticationHeaderValue("Bearer", authenticationResult.AccessToken);
}
}
我的示例与Power BI一起使用,但是可以与需要访问ServiceClientCredentials的任何对象一起使用。
您可以将Nuget包Microsoft.Identity.Client用于IConfidentialClientApplication。
答案 3 :(得分:0)
作为@verbedr answered,您可以改编 Azure.Identity client library 中的 TokenCredential
。 @antdev answered 你可以实现一个 Microsoft.Rest.ITokenProvider
。另一种选择是将两种方法结合起来,如下所示:
using Azure.Core;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.Rest
{
/// Allows an Azure.Core.TokenCredential to be the Microsoft.Rest.ITokenProvider.
public class TokenCredentialTokenProvider : Microsoft.Rest.ITokenProvider
{
readonly TokenCredential _tokenCredential;
readonly string[] _scopes;
public TokenCredentialTokenProvider(TokenCredential tokenCredential, string[] scopes)
{
_tokenCredential = tokenCredential;
_scopes = scopes;
}
public async Task<AuthenticationHeaderValue> GetAuthenticationHeaderAsync(CancellationToken cancellationToken)
{
var accessToken = await _tokenCredential.GetTokenAsync(new TokenRequestContext(_scopes), cancellationToken);
return new AuthenticationHeaderValue("Bearer", accessToken.Token);
}
}
}
它没有缓存。如果需要,您可以创建一个 CachingTokenProvider
或类似的。这可以像这样使用:
var tokenCredentials = new Azure.Identity.DefaultAzureCredential(new Azure.Identity.DefaultAzureCredentialOptions
{
AuthorityHost = Azure.Identity.AzureAuthorityHosts.AzurePublicCloud
});
var restTokenProvider = new Microsoft.Rest.TokenCredentialTokenProvider(tokenCredentials,
new string[] { "https://management.core.windows.net/.default" }
);
var restTokenCredentials = new Microsoft.Rest.TokenCredentials(restTokenProvider);
using var computeClient = new ComputeManagementClient(restTokenCredentials);
// computeClient.BaseUri = // set if using another cloud
computeClient.SubscriptionId = subscriptionId;
var vms = computeClient.VirtualMachines.ListAll();
Console.WriteLine("# of vms " + vms.Count());
这对我有用。以下是我使用的 csproj 中的相关依赖项:
<PackageReference Include="Azure.Identity" Version="1.4.0" />
<PackageReference Include="Microsoft.Rest.ClientRuntime" Version="2.3.23" />
<PackageReference Include="Microsoft.Azure.Management.Compute" Version="46.0.0" />