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)