70 строки
2.2 KiB
Go
70 строки
2.2 KiB
Go
//go:build go1.18
|
|
// +build go1.18
|
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// Licensed under the MIT License.
|
|
|
|
package azidentity_test
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
|
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
|
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
|
)
|
|
|
|
// timeoutWrapper signals ChainedTokenCredential to try another credential when managed identity times out
|
|
type timeoutWrapper struct {
|
|
cred *azidentity.ManagedIdentityCredential
|
|
timeout time.Duration
|
|
}
|
|
|
|
// GetToken implements the azcore.TokenCredential interface
|
|
func (w *timeoutWrapper) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) {
|
|
var tk azcore.AccessToken
|
|
var err error
|
|
if w.timeout > 0 {
|
|
c, cancel := context.WithTimeout(ctx, w.timeout)
|
|
defer cancel()
|
|
tk, err = w.cred.GetToken(c, opts)
|
|
if ce := c.Err(); errors.Is(ce, context.DeadlineExceeded) {
|
|
// The Context reached its deadline, probably because no managed identity is available.
|
|
// A credential unavailable error signals the chain to try its next credential, if any.
|
|
err = azidentity.NewCredentialUnavailableError("managed identity timed out")
|
|
} else {
|
|
// some managed identity implementation is available, so don't apply the timeout to future calls
|
|
w.timeout = 0
|
|
}
|
|
} else {
|
|
tk, err = w.cred.GetToken(ctx, opts)
|
|
}
|
|
return tk, err
|
|
}
|
|
|
|
// This example demonstrates a small wrapper that sets a deadline for authentication and signals
|
|
// [ChainedTokenCredential] to try another credential when managed identity authentication times
|
|
// out, as it would for example in a local development environment.
|
|
func ExampleNewChainedTokenCredential_managedIdentityTimeout() {
|
|
mic, err := azidentity.NewManagedIdentityCredential(nil)
|
|
if err != nil {
|
|
// TODO: handle error
|
|
}
|
|
azCLI, err := azidentity.NewAzureCLICredential(nil)
|
|
if err != nil {
|
|
// TODO: handle error
|
|
}
|
|
creds := []azcore.TokenCredential{
|
|
&timeoutWrapper{mic, time.Second},
|
|
azCLI,
|
|
}
|
|
chain, err := azidentity.NewChainedTokenCredential(creds, nil)
|
|
if err != nil {
|
|
// TODO: handle error
|
|
}
|
|
// TODO: construct a client with the credential chain
|
|
_ = chain
|
|
}
|