pkg/internal/pop/msal_public.go (98 lines of code) (raw):

package pop import ( "context" "fmt" "net/http" "github.com/AzureAD/microsoft-authentication-library-for-go/apps/public" ) // AcquirePoPTokenInteractive acquires a PoP token using MSAL's interactive login flow. // Requires user to authenticate via browser func AcquirePoPTokenInteractive( context context.Context, popClaims map[string]string, scopes []string, msalOptions *MsalClientOptions, ) (string, int64, error) { var client *public.Client var err error client, err = getPublicClient(msalOptions) if err != nil { return "", -1, err } popKey, err := GetSwPoPKey() if err != nil { return "", -1, err } result, err := client.AcquireTokenInteractive( context, scopes, public.WithAuthenticationScheme( &PoPAuthenticationScheme{ Host: popClaims["u"], PoPKey: popKey, }, ), public.WithTenantID(msalOptions.TenantID), ) if err != nil { return "", -1, fmt.Errorf("failed to create PoP token with interactive flow: %w", err) } return result.AccessToken, result.ExpiresOn.Unix(), nil } // AcquirePoPTokenByUsernamePassword acquires a PoP token using MSAL's username/password login flow // This flow does not require user interaction as credentials have already been provided func AcquirePoPTokenByUsernamePassword( context context.Context, popClaims map[string]string, scopes []string, username, password string, msalOptions *MsalClientOptions, ) (string, int64, error) { client, err := getPublicClient(msalOptions) if err != nil { return "", -1, err } popKey, err := GetSwPoPKey() if err != nil { return "", -1, err } result, err := client.AcquireTokenByUsernamePassword( context, scopes, username, password, public.WithAuthenticationScheme( &PoPAuthenticationScheme{ Host: popClaims["u"], PoPKey: popKey, }, ), public.WithTenantID(msalOptions.TenantID), ) if err != nil { return "", -1, fmt.Errorf("failed to create PoP token with username/password flow: %w", err) } return result.AccessToken, result.ExpiresOn.Unix(), nil } // getPublicClient returns an instance of the msal `public` client based on the provided options // The instance discovery should be disabled on private cloud func getPublicClient(msalOptions *MsalClientOptions) (*public.Client, error) { var client public.Client var err error if msalOptions == nil { return nil, fmt.Errorf("unable to create public client: MsalClientOptions is empty") } if msalOptions.Options.Transport != nil { client, err = public.New( msalOptions.ClientID, public.WithAuthority(msalOptions.Authority), public.WithHTTPClient(msalOptions.Options.Transport.(*http.Client)), public.WithInstanceDiscovery(!msalOptions.DisableInstanceDiscovery), ) } else { client, err = public.New( msalOptions.ClientID, public.WithAuthority(msalOptions.Authority), public.WithInstanceDiscovery(!msalOptions.DisableInstanceDiscovery), ) } if err != nil { return nil, fmt.Errorf("unable to create public client: %w", err) } return &client, nil }