適用於:✅Microsoft Fabric✅Azure 數據總管
本文提供適用於 Kusto 用戶端程式庫的主要驗證方法概觀。 程式碼片段顯示驗證使用者和應用程式的不同方式,讓 Kusto 叢集能夠順暢互動。 每種方法都適合不同的場景和要求。
盡可能使用受控識別,而不是使用者名稱和密碼驗證或連接字串。 受控識別提供更安全、更簡化的驗證方法。
在本文中,您將瞭解如何使用下列方式進行驗證:
受控識別驗證
用戶主體
自定義令牌提供者
先決條件
應用程式主體驗證方法
本節涵蓋使用應用程式主體進行驗證的不同方法。
受控識別驗證
受控識別有兩種類型:系統指派和使用者指派。 系統指派的受控管理身份的生命週期會與建立其的資源緊密相連。 此身份識別僅限用於一個資源。 使用者指派的受控識別可用於多個資源。 如需詳細資訊,請參閱 受控識別。
在下列範例中,將<QueryEndpointUri>和<ManagedIdentityClientId>替換為您自己的值。
重要
- 受控識別資源的物件或主體識別碼必須指派角色,才能存取 Kusto 叢集。 您可以在 Azure 入口網站 的 Kusto 叢集資源頁面的 [ 安全性 + 網路>許可權] 底下指派角色。 受控識別不應該直接附加至 Kusto 叢集。
- 本機開發環境不支援受控識別驗證。 若要測試受控識別驗證,請將應用程式部署至 Azure,或在本機工作時使用不同的驗證方法。
憑證式驗證
憑證可作為秘密,在要求權杖時驗證應用程式的身分。 有數種方法可以載入憑證,例如從計算機的本機認證存放區或磁碟載入憑證。
|在下列範例中,將 <QueryEndpointUri>、<ApplicationId>、<CertificateSubjectName>、<CertificateIssuerName>、<CertificateThumbprint>、<CertificateObject>、<AuthorityId>、<PemPublicCertificate>、<PemPrivateKey>、<privateKeyPemFilePath>、<PemCertificatePath>和 <EnableSubjectAndIssuerAuth> 取代為您自己的值。
僅使用 C# 支援來自電腦本機證書儲存的憑證:
var kcsb = new KustoConnectionStringBuilder(<QueryEndpointUri>)
.WithAadApplicationSubjectAndIssuerAuthentication(<ApplicationId>, <CertificateSubjectName>, <CertificateIssuerName>, <AuthorityId>);
重要
當您使用主體名稱和簽發者時,憑證必須安裝在本機電腦的憑證存放區中。
來自任意來源的憑證,例如磁碟上的檔案、快取或安全存放區,例如 Azure Key Vault。 憑證物件必須包含私鑰:
X509Certificate2 certificate = <CertificateObject>;
var kcsb = new KustoConnectionStringBuilder(<QueryEndpointUri>)
.WithAadApplicationCertificateAuthentication(<ApplicationId>, certificate, <AuthorityId>);
在記憶體中載入的憑證:
kcsb = KustoConnectionStringBuilder
.with_aad_application_certificate_authentication(<QueryEndpointUri>, <ApplicationId>, <PemPrivateKey>, <CertificateThumbprint>, <AuthorityId>)
主體和發行者(SNI)驗證:
kcsb = KustoConnectionStringBuilder
.with_aad_application_certificate_sni_authentication(<QueryEndpointUri>, <ApplicationId>, <PemPrivateKey>, <PemPublicCertificate>, <CertificateThumbprint>, <AuthorityId>)
在記憶體中載入的憑證,例如從檔案:
const certificate: string = await fs.promises.readFile(<privateKeyPemFilePath>, "utf8");
const kcsb = KustoConnectionStringBuilder
.withAadApplicationCertificateAuthentication(<QueryEndpointUri>, <ApplicationId>, certificate, <AuthorityId>);
從檔案載入的憑證:
const kcsb = KustoConnectionStringBuilder
.withAadApplicationCertificateAuthentication(<QueryEndpointUri>, <ApplicationId>, undefined, <AuthorityId>, <EnableSubjectAndIssuerAuth>, <PemCertificatePath>);
在記憶體中載入的憑證:
ConnectionStringBuilder kcsb = ConnectionStringBuilder
.createWithAadApplicationCertificate(<QueryEndpointUri>, <ApplicationId>, <X509Certificate>, <PrivateKey>, <AuthorityId>);
主體和發行者(SNI)驗證:
ConnectionStringBuilder kcsb = ConnectionStringBuilder
.createWithAadApplicationCertificateSubjectNameIssuer(<QueryEndpointUri>, <ApplicationId>, <PublicCertificateChain>, <PrivateKey>, <AuthorityId>
如需詳細資訊,請參閱 Kusto 連線字串。
重要
若要從 Azure Key Vault 載入憑證,您可以使用 Azure.Security.KeyVault.Certificates用戶端。
應用程式金鑰驗證
應用程式密鑰也稱為應用程式密碼,是應用程式在要求令牌時用來驗證及證明其身分識別的秘密字串。 它可作為應用程式存取受保護資源的認證形式。 應用程式金鑰通常是由識別提供者或授權伺服器產生並指派。 請務必安全地管理和保護應用程式密鑰,以防止未經授權的敏感性資訊或動作存取。
|在下列範例中,以您自己的值取代 <QueryEndpointUri>、<ApplicationId>、<ApplicationKey>、<AuthorityId>和 <AuthorityId>。
應用程式金鑰:
var kcsb = new KustoConnectionStringBuilder(<QueryEndpointUri>)
.WithAadApplicationKeyAuthentication(<ApplicationId>, <ApplicationKey>, <AuthorityId>);
kcsb = KustoConnectionStringBuilder
.with_aad_application_key_authentication(<QueryEndpointUri>, <ApplicationId>, <ApplicationKey>, <AuthorityId>)
const kcsb = KustoConnectionStringBuilder
.withAadApplicationKeyAuthentication(<QueryEndpointUri>, <ApplicationId>, <ApplicationKey>, <AuthorityId>);
ConnectionStringBuilder kcsb = ConnectionStringBuilder
.createWithAadApplicationCredentials(<QueryEndpointUri>, <ApplicationId>, <ApplicationKey>, <AuthorityId>);
具有應用程式金鑰的連接字串:
var connectionString = "Data Source=<QueryEndpointUri>;Initial Catalog=NetDefaultDB;AAD Federated Security=True;AppClientId=<ApplicationId>;AppKey=<ApplicationKey>;Authority Id=<AuthorityId>;"
var kcsb = new KustoConnectionStringBuilder(connectionString);
connectionString = "Data Source=<QueryEndpointUri>;Initial Catalog=NetDefaultDB;AAD Federated Security=True;AppClientId=<ApplicationId>;AppKey=<ApplicationKey>;Authority Id=<AuthorityId>"
kcsb = KustoConnectionStringBuilder(connectionString)
const connectionString = "Data Source=<QueryEndpointUri>;Initial Catalog=NetDefaultDB;AAD Federated Security=True;AppClientId=<ApplicationId>;AppKey=<ApplicationKey>;Authority Id=<AuthorityId>";
const kcsb = new KustoConnectionStringBuilder(connectionString)
String connectionString = "Data Source=<QueryEndpointUri>;AppClientId=<ApplicationId>;AppKey=<ApplicationKey>;Authority Id=<AuthorityId>";
ConnectionStringBuilder kcsb = new ConnectionStringBuilder(connectionString);
重要
在程式碼中硬編碼敏感資訊是不好的做法。 以純文字形式儲存敏感資訊(例如身份驗證憑證)會導致安全漏洞。 將敏感性資訊加密或安全地儲存在金鑰保存庫中。 使用加密或金鑰保存庫可確保您的秘密受到保護,並且只有授權的使用者或應用程式才能存取。
使用者主體驗證方法
本節涵蓋使用用戶主體進行驗證的不同方法。
互動式使用者登入驗證
此驗證方法會使用使用者的認證來建立與 Kusto 的安全連線。 方法會開啟網頁瀏覽器,提示使用者輸入其使用者名稱和密碼,以完成驗證程式。
|在下列範例中,以您自己的值取代 <QueryEndpointUri> 、<AuthorityId>和 <AuthorityId>。
互動式使用者登入:
var kcsb = new KustoConnectionStringBuilder(<QueryEndpointUri>)
.WithAadUserPromptAuthentication();
kcsb = KustoConnectionStringBuilder
.with_interactive_login(<QueryEndpointUri>)
const kcsb = KustoConnectionStringBuilder
.createWithUserPrompt(<QueryEndpointUri>, {tenantId: <AuthorityId>});
ConnectionStringBuilder kcsb = ConnectionStringBuilder
.createWithAadApplicationCredentials(<QueryEndpointUri>, <AuthorityId>);
Azure Command-Line 介面(CLI)驗證
此驗證方法會使用 Azure Command-Line 介面 (CLI) 來驗證並取得使用者的令牌。 執行 az login 命令表示使用者可以安全地建立連線,並擷取必要的令牌以進行驗證。 如果 Azure CLI 快取中沒有令牌,且 interactive 參數設定為 true,則可能會提示使用者登入。 如需詳細資訊,請參閱 Azure Command-Line 介面 (CLI)。
|在下列範例中,將 <QueryEndpointUri> 取代為您自己的值。
var kcsb = new KustoConnectionStringBuilder(<QueryEndpointUri>)
.WithAadAzCliAuthentication(interactive: true);
kcsb = KustoConnectionStringBuilder
.with_az_cli_authentication(<QueryEndpointUri>)
const kcsb = KustoConnectionStringBuilder
.withAzLoginIdentity(<QueryEndpointUri>);
ConnectionStringBuilder kcsb = ConnectionStringBuilder
.createWithAzureCli(<QueryEndpointUri>);
重要
只有 .NET Framework 應用程式才支援此方法。
裝置程式代碼驗證
此方法是針對缺少適當使用者介面的裝置所設計,例如IoT裝置和伺服器終端機。 它為使用者提供程式碼和 URL,以使用不同的裝置進行驗證,例如智慧型手機。 這個互動式方法需要使用者透過瀏覽器登入。
|在下列範例中,將 <QueryEndpointUri> 取代為您自己的值。
var kcsb = new KustoConnectionStringBuilder(<QueryEndpointUri>)
.WithAadDeviceCodeAuthentication((msg, uri, code) =>
{
// The callback is used to display instructions to the user on how to authenticate using the device code
Console.WriteLine("Device Code Message: {0}", msg);
Console.WriteLine("Device Code Uri: {0}", uri);
Console.WriteLine("Device Code: {0}", code);
return Task.CompletedTask;
});
kcsb = KustoConnectionStringBuilder
.with_aad_device_authentication(<QueryEndpointUri>)
const kcsb = KustoConnectionStringBuilder
.withAadDeviceAuthentication(<QueryEndpointUri>);
ConnectionStringBuilder kcsb = ConnectionStringBuilder
.createWithDeviceCode(<QueryEndpointUri>);
重要
租用戶條件式存取原則可能會封鎖裝置程式代碼驗證。
如果遭到封鎖,請選取替代驗證方法。
自訂令牌提供者驗證方法
本節涵蓋使用自定義令牌提供者進行驗證的不同方法。
聯盟管理的身份憑證認證的自定義令牌提供者
自定義令牌提供者可用來取得Microsoft Entra ID 令牌以進行驗證。 下列範例示範如何使用自定義令牌提供者,以使用同盟受控識別取得令牌。 您可以修改程式代碼以符合應用程式的需求。
|在下列範例中,以您自己的值取代 <AuthorityIdId>、<ApplicationId>、<ManagedIdentityClientId>和 <QueryEndpointUri>。
public class TokenProvider
{
private ClientAssertionCredential m_clientAssertion;
private TokenRequestContext m_tokenRequestContext;
public TokenProvider(string queryEndpointUri)
{
string resourceId = null;
try
{
// Get the appropiate resource id by querying the metadata
var httpClient = new HttpClient();
var response = httpClient.GetByteArrayAsync($"{queryEndpointUri}/v1/rest/auth/metadata").Result;
var json = JObject.Parse(Encoding.UTF8.GetString(response));
resourceId = json["AzureAD"]?["KustoServiceResourceId"]?.ToString();
// Append scope to resource id
resourceId = !string.IsNullOrWhiteSpace(resourceId) ? $"{resourceId}/.default" : null;
}
catch { /* Handle exception */}
m_tokenRequestContext = new TokenRequestContext(new string[] { resourceId ?? "https://kusto.kusto.windows.net/.default" });
// Create client assertion credential to authenticate with Kusto
m_clientAssertion = new ClientAssertionCredential
(
<AuthorityIdId>,
<ApplicationId>,
async (token) =>
{
// Get Managed Identity token
var miCredential = new ManagedIdentityCredential(<ManagedIdentityClientId>);
var miToken = await miCredential.GetTokenAsync(new TokenRequestContext(new[] {
"api://AzureADTokenExchange/.default"
})).ConfigureAwait(false);
return miToken.Token;
}
);
}
public async Task<string> GetTokenAsync()
{
var accessToken = await m_clientAssertion.GetTokenAsync(m_tokenRequestContext).ConfigureAwait(false);
return accessToken.Token;
}
}
var tokenProvider = new TokenProvider(<QueryEndpointUri>);
var kcsb = new KustoConnectionStringBuilder(<QueryEndpointUri>)
.WithAadTokenProviderAuthentication(
async () =>
{
return await tokenProvider.GetTokenAsync();
});
import requests
from azure.identity import ClientAssertionCredential, ManagedIdentityCredential
from azure.kusto.data import KustoConnectionStringBuilder
class TokenProvider:
def __init__(self, query_endpoint_uri):
self.query_endpoint_uri = query_endpoint_uri
self.resource_id = None
self.token_request_context = None
self.client_assertion = None
self._initialize()
def _initialize(self):
try:
# Get the appropriate resource id by querying the metadata
response = requests.get(f"{self.query_endpoint_uri}/v1/rest/auth/metadata")
json = response.json()
self.resource_id = json.get("AzureAD", {}).get("KustoServiceResourceId", "https://kusto.kusto.windows.net")
# Append scope to resource id
self.resource_id = f"{self.resource_id}/.default"
except Exception as error:
print(f"Error fetching metadata: {error}")
self.token_request_context = {"scopes": [self.resource_id or "https://kusto.kusto.windows.net/.default"]}
# Create client assertion credential to authenticate with Kusto
self.client_assertion = ClientAssertionCredential(
tenant_id="<AuthorityId>"
client_id="<ApplicationId>",
func=self._get_managed_identity_token
)
async def _get_managed_identity_token(self):
mi_credential = ManagedIdentityCredential()
mi_token = await mi_credential.get_token("api://AzureADTokenExchange/.default")
return mi_token.token
async def get_token_async(self):
access_token = await self.client_assertion.get_token(self.token_request_context)
return access_token.token
def main():
query_endpoint_uri = "<QueryEndpointUri>"
token_provider = TokenProvider(query_endpoint_uri)
kcsb = KustoConnectionStringBuilder.with_token_provider(
query_endpoint_uri,
token_provider.get_token_async
)
import { ManagedIdentityCredential, ClientAssertionCredential } from '@azure/identity';
import get from 'axios';
import { KustoConnectionStringBuilder } from 'azure-kusto-data';
class TokenProvider {
constructor(queryEndpointUri) {
this.queryEndpointUri = queryEndpointUri;
this.resourceId = null;
this.tokenRequestContext = null;
this.clientAssertion = null;
}
async initialize() {
try {
// Get the appropriate resource id by querying the metadata
const response = await get(`${this.queryEndpointUri}/v1/rest/auth/metadata`);
const json = response.data;
this.resourceId = json.AzureAD?.KustoServiceResourceId || 'https://kusto.kusto.windows.net';
// Append scope to resource id
this.resourceId = `${this.resourceId}/.default`;
} catch (error) {
console.error('Error fetching metadata:', error);
}
this.tokenRequestContext = { scopes: [this.resourceId || 'https://kusto.kusto.windows.net/.default'] };
// Create client assertion credential to authenticate with Kusto
this.clientAssertion = new ClientAssertionCredential(
'<AuthorityId>', // tenantId
'<ApplicationId>', // clientId
async () => {
const miCredential = new ManagedIdentityCredential();
const miToken = await miCredential.getToken({ scopes: ['api://AzureADTokenExchange/.default'] });
return miToken.token;
}
);
}
async getTokenAsync() {
const accessToken = await this.clientAssertion.getToken(this.tokenRequestContext);
return accessToken.token;
}
}
const tokenProvider = new TokenProvider("<QueryEndpointUri>");
await tokenProvider.initialize();
const kcsb = KustoConnectionStringBuilder.withAadTokenProviderAuthentication(
"<QueryEndpointUri>",
async () => {
return await tokenProvider.getTokenAsync();
}
);
public class TokenProvider {
private TokenRequestContext tokenRequestContext;
private ClientAssertionCredential clientAssertion;
public TokenProvider(String queryEndpointUri) {
String resourceId = "";
try {
// Get the appropriate resource id by querying the metadata
URL url = new URL(queryEndpointUri + "/v1/rest/auth/metadata");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.connect();
Scanner scanner = new Scanner(url.openStream(), StandardCharsets.UTF_8);
String jsonResponse = scanner.useDelimiter("\\A").next();
scanner.close();
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(jsonResponse);
resourceId = jsonNode.path("AzureAD").path("KustoServiceResourceId").asText("https://kusto.kusto.windows.net");
// Append scope to resource id
resourceId = resourceId + "/.default";
} catch (IOException e) {
System.err.println("Error fetching metadata: " + e.getMessage());
resourceId = "https://kusto.kusto.windows.net/.default";
}
tokenRequestContext = new TokenRequestContext().addScopes(resourceId);
// Create client assertion credential to authenticate with Kusto
clientAssertion = new ClientAssertionCredential(
"<AuthorityId>",
"<ApplicationId>", // clientId
() -> {
ManagedIdentityCredential miCredential = new ManagedIdentityCredential();
return miCredential.getToken(new TokenRequestContext().addScopes("api://AzureADTokenExchange/.default")).block().getToken();
}
);
}
public CompletableFuture<String> getTokenAsync() {
return clientAssertion.getToken(tokenRequestContext).thenApply(token -> token.getToken());
}
}
TokenProvider tokenProvider = new TokenProvider("<QueryEndpointUri>");
ConnectionStringBuilder kcsb = ConnectionStringBuilder.createWithAadTokenProviderAuthentication(queryEndpointUri,tokenProvider::getTokenAsync);
使用 Azure TokenCredential 驗證
建立繼承自 TokenCredential 並實作 GetToken 方法的類別,以建立自定義令牌提供者。 或者,您可以使用現有的權杖提供者,例如 DefaultAzureCredential。 當需要自定義令牌提供者時,此方法可為不同的驗證案例提供彈性。
您可以使用 DefaultAzureCredential 來支援使用受控識別驗證的生產程式代碼,或使用 Visual Studio 或 Azure CLI 測試程式代碼。
DefaultAzureCredential 可以設定為使用不同的驗證方法。
|在下列範例中,以您自己的值取代 <QueryEndpointUri> 和 <ManagedIdentityClientId>。
var credentialProvider = new DefaultAzureCredential(new DefaultAzureCredentialOptions {
ManagedIdentityClientId = <ManagedIdentityClientId>
});
var kcsb = new KustoConnectionStringBuilder(<QueryEndpointUri>)
.WithAadAzureTokenCredentialsAuthentication(credentialProvider);
from azure.identity import DefaultAzureCredential
token_credential = DefaultAzureCredential()
kcsb = KustoConnectionStringBuilder
.with_azure_token_credential(<QueryEndpointUri>, token_credential)
import { DefaultAzureCredential } from "@azure/identity";
const credential = new DefaultAzureCredential();
const kcsb = KustoConnectionStringBuilder
.withTokenCredential(<QueryEndpointUri>, credential);
注意
DefaultAzureCredential 可用來向 Azure 服務進行驗證。
它會嘗試多個驗證方法來取得令牌,並可設定為使用受控識別、Visual Studio、Azure CLI 等等。
此認證適用於測試和生產環境,因為它可以設定為使用不同的驗證方法。
如需詳細資訊,請參閱 DefaultAzureCredential 類別。
下一步