我是 AKS 和 Azure Identity 平台的新手。我有一个使用 Azure AD 集成的 AKS 群集。在具有用户分配的托管标识的 Azure VM 中,我尝试运行 C# 控制台应用程序来针对 Azure AD 进行身份验证,获取 kubeconfig 内容,然后使用 kubernetes 客户端执行一些列表操作。运行下面的代码时,我在尝试执行列表操作时收到未经授权的错误。我已确保在集群访问角色中,分配的托管标识的用户具有所有者角色。
该代码执行以下操作:
我不确定 TokenRequestContext 的范围是否正确以及 oauth 令牌请求的资源参数是否正确。
string userAssignedClientId = "0f2a4a25-e37f-4aba-942a-5c58f39eb136";
var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = userAssignedClientId });
var defaultToken = credential.GetToken(new TokenRequestContext(new[] { "https://management.azure.com/.default" })).Token;
var defaultTokenCredentials = new Microsoft.Rest.TokenCredentials(defaultToken);
var azureCredentials = new Microsoft.Azure.Management.ResourceManager.Fluent.Authentication.AzureCredentials(defaultTokenCredentials, defaultTokenCredentials, null, AzureEnvironment.AzureGlobalCloud);
var azure = Microsoft.Azure.Management.Fluent.Azure.Authenticate(azureCredentials).WithSubscription("XXX");
var kubeConfigBytes = azure.KubernetesClusters.GetUserKubeConfigContents(
"XXX",
"XXX"
);
var kubeConfigRaw = KubernetesClientConfiguration.LoadKubeConfig(new MemoryStream(kubeConfigBytes));
var authProvider = kubeConfigRaw.Users.Single().UserCredentials.AuthProvider;
if (!authProvider.Name.Equals("azure", StringComparison.OrdinalIgnoreCase))
throw new Exception("Invalid k8s auth provider!");
var httpClient = new HttpClient();
var token = string.Empty;
using (var requestMessage =
new HttpRequestMessage(HttpMethod.Get, $"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource={Uri.EscapeUriString("6dae42f8-4368-4678-94ff-3960e28e3630/.default")}&client_id={userAssignedClientId}"))
{
requestMessage.Headers.Add("Metadata", "true");
var response = await httpClient.SendAsync(requestMessage);
token = await response.Content.ReadAsStringAsync();
Console.WriteLine(token);
}
var tokenNode = JsonNode.Parse(token);
authProvider.Config["access-token"] = tokenNode["access_token"].GetValue<string>();
authProvider.Config["expires-on"] = DateTimeOffset.UtcNow.AddSeconds(double.Parse(tokenNode["expires_in"].GetValue<string>())).ToUnixTimeSeconds().ToString();
var kubeConfig = KubernetesClientConfiguration.BuildConfigFromConfigObject(kubeConfigRaw);
var kubernetes = new Kubernetes(kubeConfig);
var namespaces = kubernetes.CoreV1.ListNamespace();
foreach (var ns in namespaces.Items)
{
Console.WriteLine(ns.Metadata.Name);
var list = kubernetes.CoreV1.ListNamespacedPod(ns.Metadata.Name);
foreach (var item in list.Items)
{
Console.WriteLine(item.Metadata.Name);
}
}
如有任何帮助,我们将不胜感激!
尝试使用令牌请求中的资源,而不使用
/.default
。
所以应该是:
resource=6dae42f8-4368-4678-94ff-3960e28e3630
尝试使用
6dae42f8-4368-4678-94ff-3960e28e3630/.default
来代替访问k8s相关的访问。
management.azure.com/.default
和6dae42f8-4368-4678-94ff-3960e28e3630/.default
之间的区别在于它们在Azure中的用法和上下文。
https://management.azure.com/.default:这是一个通用资源标识符,用于获取 Azure 管理 API 的访问令牌。它主要与管理 Azure 资源(例如虚拟机、存储帐户和数据库)相关。通过 Azure AD 请求令牌时,您可以使用此 URL 作为与 Azure 管理服务交互的资源或范围。
6dae42f8-4368-4678-94ff-3960e28e3630:这是 Azure Kubernetes 服务 (AKS) AAD 服务器的应用程序 ID。它是所有 Azure 环境中的固定标识符,在对与 Azure Active Directory (AAD) 集成的 AKS 群集进行身份验证时使用。为此应用程序 ID 颁发旨在与 AKS 上的 Kubernetes API 服务器交互的访问令牌。例如,在获取令牌以验证 Kubernetes API 请求时,在 kubelogin 工具中使用此应用程序 ID( 天蓝色 )( GitHub )( 欢迎 |奥米亚根 ).
总而言之,虽然 https://management.azure.com/.default 用于一般 Azure 资源管理,但 6dae42f8-4368-4678-94ff-3960e28e3630 特定于 AKS 相关访问。