in cli/azd/pkg/auth/manager.go [202:350]
func (m *Manager) CredentialForCurrentUser(
ctx context.Context,
options *CredentialForCurrentUserOptions,
) (azcore.TokenCredential, error) {
if options == nil {
options = &CredentialForCurrentUserOptions{}
}
if m.UseExternalAuth() {
log.Printf("delegating auth to external process")
return newRemoteCredential(
m.externalAuthCfg.Endpoint,
m.externalAuthCfg.Key,
options.TenantID,
m.externalAuthCfg.Transporter), nil
}
userConfig, err := m.userConfigManager.Load()
if err != nil {
return nil, fmt.Errorf("fetching current user: %w", err)
}
if shouldUseLegacyAuth(userConfig) {
log.Printf("delegating auth to az since %s is set to true", useAzCliAuthKey)
cred, err := azidentity.NewAzureCLICredential(&azidentity.AzureCLICredentialOptions{
TenantID: options.TenantID,
})
if err != nil {
return nil, fmt.Errorf("failed to create credential: %w: %w", err, ErrNoCurrentUser)
}
return cred, nil
}
authConfig, err := m.readAuthConfig()
if err != nil {
return nil, fmt.Errorf("reading auth config: %w", err)
}
currentUser, err := readUserProperties(authConfig)
if errors.Is(err, ErrNoCurrentUser) {
// User is not logged in, not using az credentials, try CloudShell if possible
if runcontext.IsRunningInCloudShell() {
cloudShellCredential, err := m.newCredentialFromCloudShell()
if err != nil {
return nil, err
}
return cloudShellCredential, nil
}
if oneauth.Supported && strings.EqualFold(os.Getenv("IsDevBox"), "True") {
// Try logging in the active OS account. If that fails for any reason, tell the user to run `azd auth login`.
if err := m.LoginWithBrokerAccount(); err == nil {
if config, err := m.readAuthConfig(); err == nil {
user, err := readUserProperties(config)
if err == nil && user != nil && user.HomeAccountID != nil && *user.HomeAccountID != "" {
tenant := options.TenantID
if tenant == "" {
tenant = "organizations"
}
authority := m.cloud.Configuration.ActiveDirectoryAuthorityHost + tenant
return oneauth.NewCredential(authority, azdClientID, oneauth.CredentialOptions{
HomeAccountID: *user.HomeAccountID,
})
}
}
}
}
return nil, ErrNoCurrentUser
}
if currentUser.HomeAccountID != nil {
if currentUser.FromOneAuth {
tenant := options.TenantID
if tenant == "" {
tenant = "organizations"
}
authority, err := url.JoinPath(m.cloud.Configuration.ActiveDirectoryAuthorityHost, tenant)
if err != nil {
return nil, fmt.Errorf("joining authority url: %w", err)
}
return oneauth.NewCredential(authority, azdClientID, oneauth.CredentialOptions{
HomeAccountID: *currentUser.HomeAccountID,
NoPrompt: options.NoPrompt,
})
}
accounts, err := m.publicClient.Accounts(ctx)
if err != nil {
return nil, err
}
for i, account := range accounts {
if account.HomeAccountID == *currentUser.HomeAccountID {
if options.TenantID == "" {
return newAzdCredential(m.publicClient, &accounts[i], m.cloud), nil
} else {
newAuthority := m.cloud.Configuration.ActiveDirectoryAuthorityHost + options.TenantID
newOptions := make([]public.Option, 0, len(m.publicClientOptions)+1)
newOptions = append(newOptions, m.publicClientOptions...)
// It is important that this option comes after the saved public client options since it will
// override the default authority.
newOptions = append(newOptions, public.WithAuthority(newAuthority))
clientWithNewTenant, err := public.New(azdClientID, newOptions...)
if err != nil {
return nil, err
}
return newAzdCredential(
&msalPublicClientAdapter{client: &clientWithNewTenant}, &accounts[i], m.cloud), nil
}
}
}
} else if currentUser.ManagedIdentity {
clientID := ""
if currentUser.ClientID != nil {
clientID = *currentUser.ClientID
}
return m.newCredentialFromManagedIdentity(clientID)
} else if currentUser.TenantID != nil && currentUser.ClientID != nil {
// by default we used the stored tenant (i.e. the one provided with the tenant id parameter when a user ran
// `azd auth login`), but we allow an override using the options bag, when
// TenantID is non-empty and PreferFallbackTenant is not true.
tenantID := *currentUser.TenantID
if options.TenantID != "" {
tenantID = options.TenantID
}
ps, err := m.loadSecret(*currentUser.TenantID, *currentUser.ClientID)
if err != nil {
return nil, fmt.Errorf("loading secret: %w: %w", err, ErrNoCurrentUser)
}
if ps.ClientSecret != nil {
return m.newCredentialFromClientSecret(tenantID, *currentUser.ClientID, *ps.ClientSecret)
} else if ps.ClientCertificate != nil {
return m.newCredentialFromClientCertificate(tenantID, *currentUser.ClientID, *ps.ClientCertificate)
} else if ps.FederatedAuth != nil && ps.FederatedAuth.TokenProvider != nil {
return m.newCredentialFromFederatedTokenProvider(
tenantID, *currentUser.ClientID, *ps.FederatedAuth.TokenProvider, ps.FederatedAuth.ServiceConnectionID)
}
}
return nil, ErrNoCurrentUser
}