in azkustodata/kcsb.go [417:607]
func (kcsb *ConnectionStringBuilder) newTokenProvider() (*TokenProvider, error) {
tkp := &TokenProvider{}
tkp.tokenScheme = BearerType
var init func(*CloudInfo, *azcore.ClientOptions, string) (azcore.TokenCredential, error)
switch {
case !isEmpty(kcsb.AadUserID) && !isEmpty(kcsb.Password):
init = func(ci *CloudInfo, cliOpts *azcore.ClientOptions, appClientId string) (azcore.TokenCredential, error) {
opts := &azidentity.UsernamePasswordCredentialOptions{ClientOptions: *cliOpts}
cred, err := azidentity.NewUsernamePasswordCredential(kcsb.AuthorityId, appClientId, kcsb.AadUserID, kcsb.Password, opts)
if err != nil {
return nil, kustoErrors.E(kustoErrors.OpTokenProvider, kustoErrors.KOther,
fmt.Errorf("error: Couldn't retrieve client credentials using Username Password. Error: %s", err))
}
return cred, nil
}
case !isEmpty(kcsb.ApplicationClientId) && !isEmpty(kcsb.ApplicationKey):
init = func(ci *CloudInfo, cliOpts *azcore.ClientOptions, appClientId string) (azcore.TokenCredential, error) {
authorityId := kcsb.AuthorityId
if isEmpty(authorityId) {
authorityId = ci.FirstPartyAuthorityURL
}
opts := &azidentity.ClientSecretCredentialOptions{ClientOptions: *cliOpts}
cred, err := azidentity.NewClientSecretCredential(authorityId, appClientId, kcsb.ApplicationKey, opts)
if err != nil {
return nil, kustoErrors.E(kustoErrors.OpTokenProvider, kustoErrors.KOther,
fmt.Errorf("error: Couldn't retrieve client credentials using Client Secret. Error: %s", err))
}
return cred, nil
}
case !isEmpty(kcsb.ApplicationCertificatePath) || len(kcsb.ApplicationCertificateBytes) != 0:
init = func(ci *CloudInfo, cliOpts *azcore.ClientOptions, appClientId string) (azcore.TokenCredential, error) {
opts := &azidentity.ClientCertificateCredentialOptions{ClientOptions: *cliOpts}
opts.SendCertificateChain = kcsb.SendCertificateChain
bytes := kcsb.ApplicationCertificateBytes
if !isEmpty(kcsb.ApplicationCertificatePath) {
// read the certificate from the file
fileBytes, err := os.ReadFile(kcsb.ApplicationCertificatePath)
if err != nil {
return nil, kustoErrors.E(kustoErrors.OpTokenProvider, kustoErrors.KOther,
fmt.Errorf("error: Couldn't read certificate file: %s", err))
}
bytes = fileBytes
}
cert, thumprintKey, err := azidentity.ParseCertificates(bytes, kcsb.ApplicationCertificatePassword)
if err != nil {
return nil, kustoErrors.E(kustoErrors.OpTokenProvider, kustoErrors.KOther, err)
}
cred, err := azidentity.NewClientCertificateCredential(kcsb.AuthorityId, appClientId, cert, thumprintKey, opts)
if err != nil {
return nil, kustoErrors.E(kustoErrors.OpTokenProvider, kustoErrors.KOther,
fmt.Errorf("error: Couldn't retrieve client credentials using Application Certificate: %s", err))
}
return cred, nil
}
case kcsb.MsiAuthentication:
init = func(ci *CloudInfo, cliOpts *azcore.ClientOptions, appClientId string) (azcore.TokenCredential, error) {
opts := &azidentity.ManagedIdentityCredentialOptions{ClientOptions: *cliOpts}
// legacy kcsb.ManagedServiceIdentity field takes precedence over
// new kcsb.ManagedServiceIdentityClientId field which takes precedence over
// new kcsb.ManagedServiceIdentityResourceId field
// if no client id is provided, the logic falls back to set up
// the system assigned identity
if !isEmpty(kcsb.ManagedServiceIdentityClientId) {
opts.ID = azidentity.ClientID(kcsb.ManagedServiceIdentityClientId)
} else if !isEmpty(kcsb.ManagedServiceIdentityResourceId) {
opts.ID = azidentity.ResourceID(kcsb.ManagedServiceIdentityResourceId)
}
cred, err := azidentity.NewManagedIdentityCredential(opts)
if err != nil {
return nil, kustoErrors.E(kustoErrors.OpTokenProvider, kustoErrors.KOther,
fmt.Errorf("error: Couldn't retrieve client credentials using Managed Identity: %s", err))
}
return cred, nil
}
case kcsb.WorkloadAuthentication:
init = func(ci *CloudInfo, cliOpts *azcore.ClientOptions, appClientId string) (azcore.TokenCredential, error) {
opts := &azidentity.WorkloadIdentityCredentialOptions{ClientOptions: *cliOpts}
if !isEmpty(kcsb.ApplicationClientId) {
opts.ClientID = kcsb.ApplicationClientId
}
if !isEmpty(kcsb.FederationTokenFilePath) {
opts.TokenFilePath = kcsb.FederationTokenFilePath
}
if !isEmpty(kcsb.AuthorityId) {
opts.TenantID = kcsb.AuthorityId
}
cred, err := azidentity.NewWorkloadIdentityCredential(opts)
if err != nil {
return nil, kustoErrors.E(kustoErrors.OpTokenProvider, kustoErrors.KOther,
fmt.Errorf("error: Couldn't retrieve client credentials using Workload Identity: %s", err))
}
return cred, nil
}
case !isEmpty(kcsb.UserToken):
{
tkp.customToken = kcsb.UserToken
}
case !isEmpty(kcsb.ApplicationToken):
{
tkp.customToken = kcsb.ApplicationToken
}
case kcsb.AzCli:
init = func(ci *CloudInfo, cliOpts *azcore.ClientOptions, appClientId string) (azcore.TokenCredential, error) {
authorityId := kcsb.AuthorityId
if isEmpty(authorityId) {
authorityId = ci.FirstPartyAuthorityURL
}
opts := &azidentity.AzureCLICredentialOptions{}
opts.TenantID = kcsb.AuthorityId
cred, err := azidentity.NewAzureCLICredential(opts)
if err != nil {
return nil, kustoErrors.E(kustoErrors.OpTokenProvider, kustoErrors.KOther,
fmt.Errorf("error: Couldn't retrieve client credentials using Azure CLI: %s", err))
}
return cred, nil
}
case kcsb.DefaultAuth:
init = func(ci *CloudInfo, cliOpts *azcore.ClientOptions, appClientId string) (azcore.TokenCredential, error) {
//Default Azure authentication
opts := &azidentity.DefaultAzureCredentialOptions{}
opts.ClientOptions = *cliOpts
if kcsb.ClientOptions != nil {
opts.ClientOptions = *kcsb.ClientOptions
}
if !isEmpty(kcsb.AuthorityId) {
opts.TenantID = kcsb.AuthorityId
}
cred, err := azidentity.NewDefaultAzureCredential(opts)
if err != nil {
return nil, kustoErrors.E(kustoErrors.OpTokenProvider, kustoErrors.KOther,
fmt.Errorf("error: Couldn't retrieve client credentials for DefaultAzureCredential: %s", err))
}
return cred, nil
}
case kcsb.TokenCredential != nil:
init = func(ci *CloudInfo, cliOpts *azcore.ClientOptions, appClientId string) (azcore.TokenCredential, error) {
return kcsb.TokenCredential, nil
}
case kcsb.InteractiveLogin || kcsb.AadFederatedSecurity: // If AadFed is set, but no other auth method is set, default to interactive login
init = func(ci *CloudInfo, cliOpts *azcore.ClientOptions, appClientId string) (azcore.TokenCredential, error) {
inOpts := &azidentity.InteractiveBrowserCredentialOptions{}
inOpts.ClientID = ci.KustoClientAppID
inOpts.TenantID = kcsb.AuthorityId
inOpts.RedirectURL = ci.KustoClientRedirectURI
inOpts.ClientOptions = *cliOpts
cred, err := azidentity.NewInteractiveBrowserCredential(inOpts)
if err != nil {
return nil, kustoErrors.E(kustoErrors.OpTokenProvider, kustoErrors.KOther,
fmt.Errorf("error: Couldn't retrieve client credentials using Interactive Login. "+
"Error: %s", err))
}
return cred, nil
}
}
if init != nil {
tkp.setInit(kcsb, init)
}
return tkp, nil
}