應用程式驗證方法
本文內容
適用於:✅Microsoft Fabric ✅Azure 數據總管
本檔提供 Kusto 用戶端連結庫可用之驗證方法的主要方法概觀。 提供的代碼段示範驗證使用者和應用程式的不同方法,讓 Kusto 叢集能夠順暢地互動。 每個方法都適用於不同的案例和需求。
在可能的情況下,建議您使用受控識別,而不是使用者名稱和密碼驗證或連接字串。 受控識別提供更安全且簡化的驗證方法。
在本文中,您將瞭解如何使用下列方式進行驗證:
先決條件
應用程式主體驗證方法
本節涵蓋使用應用程式主體進行驗證的不同方法。
受控識別驗證
受控識別有兩種類型:系統指派和使用者指派。 系統指派的受控識別,其生命週期與建立它們的資源緊密相連。 此身分識別僅限於一個資源。 使用者指派的受控識別可用於多個資源。 如需詳細資訊,請參閱 受控識別 。
|在下列範例中,以您自己的值取代 <QueryEndpointUri>
和 <ManagedIdentityClientId>
。
重要
受管理識別資源的物件 ID 或主體 ID 必須被指派角色才能存取 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 類別 。
下一步