azure-sdk-for-go/sdk/azidentity/authentication_record.go

96 строки
3.1 KiB
Go

//go:build go1.18
// +build go1.18
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package azidentity
import (
"encoding/json"
"errors"
"fmt"
"net/url"
"strings"
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/public"
)
var supportedAuthRecordVersions = []string{"1.0"}
// AuthenticationRecord is non-secret account information about an authenticated user that user credentials such as
// [DeviceCodeCredential] and [InteractiveBrowserCredential] can use to access previously cached authentication
// data. Call these credentials' Authenticate method to get an AuthenticationRecord for a user.
type AuthenticationRecord struct {
// Authority is the URL of the authority that issued the token.
Authority string `json:"authority"`
// ClientID is the ID of the application that authenticated the user.
ClientID string `json:"clientId"`
// HomeAccountID uniquely identifies the account.
HomeAccountID string `json:"homeAccountId"`
// TenantID identifies the tenant in which the user authenticated.
TenantID string `json:"tenantId"`
// Username is the user's preferred username.
Username string `json:"username"`
// Version of the AuthenticationRecord.
Version string `json:"version"`
}
// UnmarshalJSON implements json.Unmarshaler for AuthenticationRecord
func (a *AuthenticationRecord) UnmarshalJSON(b []byte) error {
// Default unmarshaling is fine but we want to return an error if the record's version isn't supported i.e., we
// want to inspect the unmarshalled values before deciding whether to return an error. Unmarshaling a formally
// different type enables this by assigning all the fields without recursing into this method.
type r AuthenticationRecord
err := json.Unmarshal(b, (*r)(a))
if err != nil {
return err
}
if a.Version == "" {
return errors.New("AuthenticationRecord must have a version")
}
for _, v := range supportedAuthRecordVersions {
if a.Version == v {
return nil
}
}
return fmt.Errorf("unsupported AuthenticationRecord version %q. This module supports %v", a.Version, supportedAuthRecordVersions)
}
// account returns the AuthenticationRecord as an MSAL Account. The account is zero-valued when the AuthenticationRecord is zero-valued.
func (a *AuthenticationRecord) account() public.Account {
return public.Account{
Environment: a.Authority,
HomeAccountID: a.HomeAccountID,
PreferredUsername: a.Username,
}
}
func newAuthenticationRecord(ar public.AuthResult) (AuthenticationRecord, error) {
u, err := url.Parse(ar.IDToken.Issuer)
if err != nil {
return AuthenticationRecord{}, fmt.Errorf("Authenticate expected a URL issuer but got %q", ar.IDToken.Issuer)
}
tenant := ar.IDToken.TenantID
if tenant == "" {
tenant = strings.Trim(u.Path, "/")
}
username := ar.IDToken.PreferredUsername
if username == "" {
username = ar.IDToken.UPN
}
return AuthenticationRecord{
Authority: fmt.Sprintf("%s://%s", u.Scheme, u.Host),
ClientID: ar.IDToken.Audience,
HomeAccountID: ar.Account.HomeAccountID,
TenantID: tenant,
Username: username,
Version: "1.0",
}, nil
}