client_secret_credential.go

 1//go:build go1.18
 2// +build go1.18
 3
 4// Copyright (c) Microsoft Corporation. All rights reserved.
 5// Licensed under the MIT License.
 6
 7package azidentity
 8
 9import (
10	"context"
11
12	"github.com/Azure/azure-sdk-for-go/sdk/azcore"
13	"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
14	"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
15	"github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential"
16)
17
18const credNameSecret = "ClientSecretCredential"
19
20// ClientSecretCredentialOptions contains optional parameters for ClientSecretCredential.
21type ClientSecretCredentialOptions struct {
22	azcore.ClientOptions
23
24	// AdditionallyAllowedTenants specifies additional tenants for which the credential may acquire tokens.
25	// Add the wildcard value "*" to allow the credential to acquire tokens for any tenant in which the
26	// application is registered.
27	AdditionallyAllowedTenants []string
28
29	// DisableInstanceDiscovery should be set true only by applications authenticating in disconnected clouds, or
30	// private clouds such as Azure Stack. It determines whether the credential requests Microsoft Entra instance metadata
31	// from https://login.microsoft.com before authenticating. Setting this to true will skip this request, making
32	// the application responsible for ensuring the configured authority is valid and trustworthy.
33	DisableInstanceDiscovery bool
34
35	// tokenCachePersistenceOptions enables persistent token caching when not nil.
36	tokenCachePersistenceOptions *tokenCachePersistenceOptions
37}
38
39// ClientSecretCredential authenticates an application with a client secret.
40type ClientSecretCredential struct {
41	client *confidentialClient
42}
43
44// NewClientSecretCredential constructs a ClientSecretCredential. Pass nil for options to accept defaults.
45func NewClientSecretCredential(tenantID string, clientID string, clientSecret string, options *ClientSecretCredentialOptions) (*ClientSecretCredential, error) {
46	if options == nil {
47		options = &ClientSecretCredentialOptions{}
48	}
49	cred, err := confidential.NewCredFromSecret(clientSecret)
50	if err != nil {
51		return nil, err
52	}
53	msalOpts := confidentialClientOptions{
54		AdditionallyAllowedTenants:   options.AdditionallyAllowedTenants,
55		ClientOptions:                options.ClientOptions,
56		DisableInstanceDiscovery:     options.DisableInstanceDiscovery,
57		tokenCachePersistenceOptions: options.tokenCachePersistenceOptions,
58	}
59	c, err := newConfidentialClient(tenantID, clientID, credNameSecret, cred, msalOpts)
60	if err != nil {
61		return nil, err
62	}
63	return &ClientSecretCredential{client: c}, nil
64}
65
66// GetToken requests an access token from Microsoft Entra ID. This method is called automatically by Azure SDK clients.
67func (c *ClientSecretCredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) {
68	var err error
69	ctx, endSpan := runtime.StartSpan(ctx, credNameSecret+"."+traceOpGetToken, c.client.azClient.Tracer(), nil)
70	defer func() { endSpan(err) }()
71	tk, err := c.client.GetToken(ctx, opts)
72	return tk, err
73}
74
75var _ azcore.TokenCredential = (*ClientSecretCredential)(nil)