func()

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
}