1 package auth
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 import (
18 "bytes"
19 "context"
20 "encoding/binary"
21 "encoding/json"
22 "errors"
23 "fmt"
24 "io/ioutil"
25 "log"
26 "os"
27 "strings"
28 "unicode/utf16"
29
30 "github.com/Azure/go-autorest/autorest"
31 "github.com/Azure/go-autorest/autorest/adal"
32 "github.com/Azure/go-autorest/autorest/azure"
33 "github.com/Azure/go-autorest/autorest/azure/cli"
34 "github.com/Azure/go-autorest/logger"
35 "github.com/dimchansky/utfbom"
36 )
37
38
39 const (
40 SubscriptionID = "AZURE_SUBSCRIPTION_ID"
41 TenantID = "AZURE_TENANT_ID"
42 AuxiliaryTenantIDs = "AZURE_AUXILIARY_TENANT_IDS"
43 ClientID = "AZURE_CLIENT_ID"
44 ClientSecret = "AZURE_CLIENT_SECRET"
45 CertificatePath = "AZURE_CERTIFICATE_PATH"
46 CertificatePassword = "AZURE_CERTIFICATE_PASSWORD"
47 Username = "AZURE_USERNAME"
48 Password = "AZURE_PASSWORD"
49 EnvironmentName = "AZURE_ENVIRONMENT"
50 Resource = "AZURE_AD_RESOURCE"
51 ActiveDirectoryEndpoint = "ActiveDirectoryEndpoint"
52 ResourceManagerEndpoint = "ResourceManagerEndpoint"
53 GraphResourceID = "GraphResourceID"
54 SQLManagementEndpoint = "SQLManagementEndpoint"
55 GalleryEndpoint = "GalleryEndpoint"
56 ManagementEndpoint = "ManagementEndpoint"
57 )
58
59
60
61
62
63
64 func NewAuthorizerFromEnvironment() (autorest.Authorizer, error) {
65 logger.Instance.Writeln(logger.LogInfo, "NewAuthorizerFromEnvironment() determining authentication mechanism")
66 settings, err := GetSettingsFromEnvironment()
67 if err != nil {
68 return nil, err
69 }
70 return settings.GetAuthorizer()
71 }
72
73
74
75
76
77
78 func NewAuthorizerFromEnvironmentWithResource(resource string) (autorest.Authorizer, error) {
79 logger.Instance.Writeln(logger.LogInfo, "NewAuthorizerFromEnvironmentWithResource() determining authentication mechanism")
80 settings, err := GetSettingsFromEnvironment()
81 if err != nil {
82 return nil, err
83 }
84 settings.Values[Resource] = resource
85 return settings.GetAuthorizer()
86 }
87
88
89 type EnvironmentSettings struct {
90 Values map[string]string
91 Environment azure.Environment
92 }
93
94
95 func GetSettingsFromEnvironment() (s EnvironmentSettings, err error) {
96 s = EnvironmentSettings{
97 Values: map[string]string{},
98 }
99 s.setValue(SubscriptionID)
100 s.setValue(TenantID)
101 s.setValue(AuxiliaryTenantIDs)
102 s.setValue(ClientID)
103 s.setValue(ClientSecret)
104 s.setValue(CertificatePath)
105 s.setValue(CertificatePassword)
106 s.setValue(Username)
107 s.setValue(Password)
108 s.setValue(EnvironmentName)
109 s.setValue(Resource)
110 if v := s.Values[EnvironmentName]; v == "" {
111 s.Environment = azure.PublicCloud
112 } else {
113 s.Environment, err = azure.EnvironmentFromName(v)
114 }
115 if s.Values[Resource] == "" {
116 s.Values[Resource] = s.Environment.ResourceManagerEndpoint
117 }
118 return
119 }
120
121
122 func (settings EnvironmentSettings) GetSubscriptionID() string {
123 return settings.Values[SubscriptionID]
124 }
125
126
127 func (settings EnvironmentSettings) setValue(key string) {
128 if v := os.Getenv(key); v != "" {
129 logger.Instance.Writef(logger.LogInfo, "GetSettingsFromEnvironment() found environment var %s\n", key)
130 settings.Values[key] = v
131 }
132 }
133
134
135 func (settings EnvironmentSettings) getClientAndTenant() (string, string) {
136 clientID := settings.Values[ClientID]
137 tenantID := settings.Values[TenantID]
138 return clientID, tenantID
139 }
140
141
142
143 func (settings EnvironmentSettings) GetClientCredentials() (ClientCredentialsConfig, error) {
144 secret := settings.Values[ClientSecret]
145 if secret == "" {
146 logger.Instance.Writeln(logger.LogInfo, "EnvironmentSettings.GetClientCredentials() missing client secret")
147 return ClientCredentialsConfig{}, errors.New("missing client secret")
148 }
149 clientID, tenantID := settings.getClientAndTenant()
150 config := NewClientCredentialsConfig(clientID, secret, tenantID)
151 config.AADEndpoint = settings.Environment.ActiveDirectoryEndpoint
152 config.Resource = settings.Values[Resource]
153 if auxTenants, ok := settings.Values[AuxiliaryTenantIDs]; ok {
154 config.AuxTenants = strings.Split(auxTenants, ";")
155 for i := range config.AuxTenants {
156 config.AuxTenants[i] = strings.TrimSpace(config.AuxTenants[i])
157 }
158 }
159 return config, nil
160 }
161
162
163
164 func (settings EnvironmentSettings) GetClientCertificate() (ClientCertificateConfig, error) {
165 certPath := settings.Values[CertificatePath]
166 if certPath == "" {
167 logger.Instance.Writeln(logger.LogInfo, "EnvironmentSettings.GetClientCertificate() missing certificate path")
168 return ClientCertificateConfig{}, errors.New("missing certificate path")
169 }
170 certPwd := settings.Values[CertificatePassword]
171 clientID, tenantID := settings.getClientAndTenant()
172 config := NewClientCertificateConfig(certPath, certPwd, clientID, tenantID)
173 config.AADEndpoint = settings.Environment.ActiveDirectoryEndpoint
174 config.Resource = settings.Values[Resource]
175 return config, nil
176 }
177
178
179
180 func (settings EnvironmentSettings) GetUsernamePassword() (UsernamePasswordConfig, error) {
181 username := settings.Values[Username]
182 password := settings.Values[Password]
183 if username == "" || password == "" {
184 logger.Instance.Writeln(logger.LogInfo, "EnvironmentSettings.GetUsernamePassword() missing username and/or password")
185 return UsernamePasswordConfig{}, errors.New("missing username/password")
186 }
187 clientID, tenantID := settings.getClientAndTenant()
188 config := NewUsernamePasswordConfig(username, password, clientID, tenantID)
189 config.AADEndpoint = settings.Environment.ActiveDirectoryEndpoint
190 config.Resource = settings.Values[Resource]
191 return config, nil
192 }
193
194
195 func (settings EnvironmentSettings) GetMSI() MSIConfig {
196 config := NewMSIConfig()
197 config.Resource = settings.Values[Resource]
198 config.ClientID = settings.Values[ClientID]
199 return config
200 }
201
202
203 func (settings EnvironmentSettings) GetDeviceFlow() DeviceFlowConfig {
204 clientID, tenantID := settings.getClientAndTenant()
205 config := NewDeviceFlowConfig(clientID, tenantID)
206 config.AADEndpoint = settings.Environment.ActiveDirectoryEndpoint
207 config.Resource = settings.Values[Resource]
208 return config
209 }
210
211
212
213
214
215
216 func (settings EnvironmentSettings) GetAuthorizer() (autorest.Authorizer, error) {
217
218 if c, e := settings.GetClientCredentials(); e == nil {
219 logger.Instance.Writeln(logger.LogInfo, "EnvironmentSettings.GetAuthorizer() using client secret credentials")
220 return c.Authorizer()
221 }
222
223
224 if c, e := settings.GetClientCertificate(); e == nil {
225 logger.Instance.Writeln(logger.LogInfo, "EnvironmentSettings.GetAuthorizer() using client certificate credentials")
226 return c.Authorizer()
227 }
228
229
230 if c, e := settings.GetUsernamePassword(); e == nil {
231 logger.Instance.Writeln(logger.LogInfo, "EnvironmentSettings.GetAuthorizer() using user name/password credentials")
232 return c.Authorizer()
233 }
234
235
236 if !adal.MSIAvailable(context.Background(), nil) {
237 return nil, errors.New("MSI not available")
238 }
239 logger.Instance.Writeln(logger.LogInfo, "EnvironmentSettings.GetAuthorizer() using MSI authentication")
240 return settings.GetMSI().Authorizer()
241 }
242
243
244
245
246
247
248 func NewAuthorizerFromFile(resourceBaseURI string) (autorest.Authorizer, error) {
249 settings, err := GetSettingsFromFile()
250 if err != nil {
251 return nil, err
252 }
253 return settings.GetAuthorizer(resourceBaseURI)
254 }
255
256
257
258
259
260 func (settings FileSettings) GetAuthorizer(resourceBaseURI string) (autorest.Authorizer, error) {
261 if resourceBaseURI == "" {
262 resourceBaseURI = azure.PublicCloud.ServiceManagementEndpoint
263 }
264 if a, err := settings.ClientCredentialsAuthorizer(resourceBaseURI); err == nil {
265 return a, err
266 }
267 if a, err := settings.ClientCertificateAuthorizer(resourceBaseURI); err == nil {
268 return a, err
269 }
270 return nil, errors.New("auth file missing client and certificate credentials")
271 }
272
273
274
275
276
277 func NewAuthorizerFromFileWithResource(resource string) (autorest.Authorizer, error) {
278 s, err := GetSettingsFromFile()
279 if err != nil {
280 return nil, err
281 }
282 if a, err := s.ClientCredentialsAuthorizerWithResource(resource); err == nil {
283 return a, err
284 }
285 if a, err := s.ClientCertificateAuthorizerWithResource(resource); err == nil {
286 return a, err
287 }
288 return nil, errors.New("auth file missing client and certificate credentials")
289 }
290
291
292 func NewAuthorizerFromCLI() (autorest.Authorizer, error) {
293 settings, err := GetSettingsFromEnvironment()
294 if err != nil {
295 return nil, err
296 }
297
298 if settings.Values[Resource] == "" {
299 settings.Values[Resource] = settings.Environment.ResourceManagerEndpoint
300 }
301
302 return NewAuthorizerFromCLIWithResource(settings.Values[Resource])
303 }
304
305
306 func NewAuthorizerFromCLIWithResource(resource string) (autorest.Authorizer, error) {
307 token, err := cli.GetTokenFromCLI(resource)
308 if err != nil {
309 return nil, err
310 }
311
312 adalToken, err := token.ToADALToken()
313 if err != nil {
314 return nil, err
315 }
316
317 return autorest.NewBearerAuthorizer(&adalToken), nil
318 }
319
320
321 func GetSettingsFromFile() (FileSettings, error) {
322 s := FileSettings{}
323 fileLocation := os.Getenv("AZURE_AUTH_LOCATION")
324 if fileLocation == "" {
325 return s, errors.New("environment variable AZURE_AUTH_LOCATION is not set")
326 }
327
328 contents, err := ioutil.ReadFile(fileLocation)
329 if err != nil {
330 return s, err
331 }
332
333
334 decoded, err := decode(contents)
335 if err != nil {
336 return s, err
337 }
338
339 authFile := map[string]interface{}{}
340 err = json.Unmarshal(decoded, &authFile)
341 if err != nil {
342 return s, err
343 }
344
345 s.Values = map[string]string{}
346 s.setKeyValue(ClientID, authFile["clientId"])
347 s.setKeyValue(ClientSecret, authFile["clientSecret"])
348 s.setKeyValue(CertificatePath, authFile["clientCertificate"])
349 s.setKeyValue(CertificatePassword, authFile["clientCertificatePassword"])
350 s.setKeyValue(SubscriptionID, authFile["subscriptionId"])
351 s.setKeyValue(TenantID, authFile["tenantId"])
352 s.setKeyValue(ActiveDirectoryEndpoint, authFile["activeDirectoryEndpointUrl"])
353 s.setKeyValue(ResourceManagerEndpoint, authFile["resourceManagerEndpointUrl"])
354 s.setKeyValue(GraphResourceID, authFile["activeDirectoryGraphResourceId"])
355 s.setKeyValue(SQLManagementEndpoint, authFile["sqlManagementEndpointUrl"])
356 s.setKeyValue(GalleryEndpoint, authFile["galleryEndpointUrl"])
357 s.setKeyValue(ManagementEndpoint, authFile["managementEndpointUrl"])
358 return s, nil
359 }
360
361
362 type FileSettings struct {
363 Values map[string]string
364 }
365
366
367 func (settings FileSettings) GetSubscriptionID() string {
368 return settings.Values[SubscriptionID]
369 }
370
371
372 func (settings FileSettings) setKeyValue(key string, val interface{}) {
373 if val != nil {
374 settings.Values[key] = val.(string)
375 }
376 }
377
378
379 func (settings FileSettings) getAADEndpoint() string {
380 if v, ok := settings.Values[ActiveDirectoryEndpoint]; ok {
381 return v
382 }
383 return azure.PublicCloud.ActiveDirectoryEndpoint
384 }
385
386
387 func (settings FileSettings) ServicePrincipalTokenFromClientCredentials(baseURI string) (*adal.ServicePrincipalToken, error) {
388 resource, err := settings.getResourceForToken(baseURI)
389 if err != nil {
390 return nil, err
391 }
392 return settings.ServicePrincipalTokenFromClientCredentialsWithResource(resource)
393 }
394
395
396 func (settings FileSettings) ClientCredentialsAuthorizer(baseURI string) (autorest.Authorizer, error) {
397 resource, err := settings.getResourceForToken(baseURI)
398 if err != nil {
399 return nil, err
400 }
401 return settings.ClientCredentialsAuthorizerWithResource(resource)
402 }
403
404
405
406 func (settings FileSettings) ServicePrincipalTokenFromClientCredentialsWithResource(resource string) (*adal.ServicePrincipalToken, error) {
407 if _, ok := settings.Values[ClientSecret]; !ok {
408 return nil, errors.New("missing client secret")
409 }
410 config, err := adal.NewOAuthConfig(settings.getAADEndpoint(), settings.Values[TenantID])
411 if err != nil {
412 return nil, err
413 }
414 return adal.NewServicePrincipalToken(*config, settings.Values[ClientID], settings.Values[ClientSecret], resource)
415 }
416
417 func (settings FileSettings) clientCertificateConfigWithResource(resource string) (ClientCertificateConfig, error) {
418 if _, ok := settings.Values[CertificatePath]; !ok {
419 return ClientCertificateConfig{}, errors.New("missing certificate path")
420 }
421 cfg := NewClientCertificateConfig(settings.Values[CertificatePath], settings.Values[CertificatePassword], settings.Values[ClientID], settings.Values[TenantID])
422 cfg.AADEndpoint = settings.getAADEndpoint()
423 cfg.Resource = resource
424 return cfg, nil
425 }
426
427
428 func (settings FileSettings) ClientCredentialsAuthorizerWithResource(resource string) (autorest.Authorizer, error) {
429 spToken, err := settings.ServicePrincipalTokenFromClientCredentialsWithResource(resource)
430 if err != nil {
431 return nil, err
432 }
433 return autorest.NewBearerAuthorizer(spToken), nil
434 }
435
436
437 func (settings FileSettings) ServicePrincipalTokenFromClientCertificate(baseURI string) (*adal.ServicePrincipalToken, error) {
438 resource, err := settings.getResourceForToken(baseURI)
439 if err != nil {
440 return nil, err
441 }
442 return settings.ServicePrincipalTokenFromClientCertificateWithResource(resource)
443 }
444
445
446 func (settings FileSettings) ClientCertificateAuthorizer(baseURI string) (autorest.Authorizer, error) {
447 resource, err := settings.getResourceForToken(baseURI)
448 if err != nil {
449 return nil, err
450 }
451 return settings.ClientCertificateAuthorizerWithResource(resource)
452 }
453
454
455 func (settings FileSettings) ServicePrincipalTokenFromClientCertificateWithResource(resource string) (*adal.ServicePrincipalToken, error) {
456 cfg, err := settings.clientCertificateConfigWithResource(resource)
457 if err != nil {
458 return nil, err
459 }
460 return cfg.ServicePrincipalToken()
461 }
462
463
464 func (settings FileSettings) ClientCertificateAuthorizerWithResource(resource string) (autorest.Authorizer, error) {
465 cfg, err := settings.clientCertificateConfigWithResource(resource)
466 if err != nil {
467 return nil, err
468 }
469 return cfg.Authorizer()
470 }
471
472 func decode(b []byte) ([]byte, error) {
473 reader, enc := utfbom.Skip(bytes.NewReader(b))
474
475 switch enc {
476 case utfbom.UTF16LittleEndian:
477 u16 := make([]uint16, (len(b)/2)-1)
478 err := binary.Read(reader, binary.LittleEndian, &u16)
479 if err != nil {
480 return nil, err
481 }
482 return []byte(string(utf16.Decode(u16))), nil
483 case utfbom.UTF16BigEndian:
484 u16 := make([]uint16, (len(b)/2)-1)
485 err := binary.Read(reader, binary.BigEndian, &u16)
486 if err != nil {
487 return nil, err
488 }
489 return []byte(string(utf16.Decode(u16))), nil
490 }
491 return ioutil.ReadAll(reader)
492 }
493
494 func (settings FileSettings) getResourceForToken(baseURI string) (string, error) {
495
496
497
498
499 if !strings.HasSuffix(baseURI, "/") {
500 baseURI += "/"
501 }
502 switch baseURI {
503 case azure.PublicCloud.ServiceManagementEndpoint:
504 return settings.Values[ManagementEndpoint], nil
505 case azure.PublicCloud.ResourceManagerEndpoint:
506 return settings.Values[ResourceManagerEndpoint], nil
507 case azure.PublicCloud.ActiveDirectoryEndpoint:
508 return settings.Values[ActiveDirectoryEndpoint], nil
509 case azure.PublicCloud.GalleryEndpoint:
510 return settings.Values[GalleryEndpoint], nil
511 case azure.PublicCloud.GraphEndpoint:
512 return settings.Values[GraphResourceID], nil
513 }
514 return "", fmt.Errorf("auth: base URI not found in endpoints")
515 }
516
517
518
519 func NewClientCredentialsConfig(clientID string, clientSecret string, tenantID string) ClientCredentialsConfig {
520 return ClientCredentialsConfig{
521 ClientID: clientID,
522 ClientSecret: clientSecret,
523 TenantID: tenantID,
524 Resource: azure.PublicCloud.ResourceManagerEndpoint,
525 AADEndpoint: azure.PublicCloud.ActiveDirectoryEndpoint,
526 }
527 }
528
529
530
531 func NewClientCertificateConfig(certificatePath string, certificatePassword string, clientID string, tenantID string) ClientCertificateConfig {
532 return ClientCertificateConfig{
533 CertificatePath: certificatePath,
534 CertificatePassword: certificatePassword,
535 ClientID: clientID,
536 TenantID: tenantID,
537 Resource: azure.PublicCloud.ResourceManagerEndpoint,
538 AADEndpoint: azure.PublicCloud.ActiveDirectoryEndpoint,
539 }
540 }
541
542
543
544 func NewUsernamePasswordConfig(username string, password string, clientID string, tenantID string) UsernamePasswordConfig {
545 return UsernamePasswordConfig{
546 Username: username,
547 Password: password,
548 ClientID: clientID,
549 TenantID: tenantID,
550 Resource: azure.PublicCloud.ResourceManagerEndpoint,
551 AADEndpoint: azure.PublicCloud.ActiveDirectoryEndpoint,
552 }
553 }
554
555
556 func NewMSIConfig() MSIConfig {
557 return MSIConfig{
558 Resource: azure.PublicCloud.ResourceManagerEndpoint,
559 }
560 }
561
562
563
564 func NewDeviceFlowConfig(clientID string, tenantID string) DeviceFlowConfig {
565 return DeviceFlowConfig{
566 ClientID: clientID,
567 TenantID: tenantID,
568 Resource: azure.PublicCloud.ResourceManagerEndpoint,
569 AADEndpoint: azure.PublicCloud.ActiveDirectoryEndpoint,
570 }
571 }
572
573
574 type AuthorizerConfig interface {
575 Authorizer() (autorest.Authorizer, error)
576 }
577
578
579 type ClientCredentialsConfig struct {
580 ClientID string
581 ClientSecret string
582 TenantID string
583 AuxTenants []string
584 AADEndpoint string
585 Resource string
586 }
587
588
589 func (ccc ClientCredentialsConfig) ServicePrincipalToken() (*adal.ServicePrincipalToken, error) {
590 oauthConfig, err := adal.NewOAuthConfig(ccc.AADEndpoint, ccc.TenantID)
591 if err != nil {
592 return nil, err
593 }
594 return adal.NewServicePrincipalToken(*oauthConfig, ccc.ClientID, ccc.ClientSecret, ccc.Resource)
595 }
596
597
598 func (ccc ClientCredentialsConfig) MultiTenantServicePrincipalToken() (*adal.MultiTenantServicePrincipalToken, error) {
599 oauthConfig, err := adal.NewMultiTenantOAuthConfig(ccc.AADEndpoint, ccc.TenantID, ccc.AuxTenants, adal.OAuthOptions{})
600 if err != nil {
601 return nil, err
602 }
603 return adal.NewMultiTenantServicePrincipalToken(oauthConfig, ccc.ClientID, ccc.ClientSecret, ccc.Resource)
604 }
605
606
607 func (ccc ClientCredentialsConfig) Authorizer() (autorest.Authorizer, error) {
608 if len(ccc.AuxTenants) == 0 {
609 spToken, err := ccc.ServicePrincipalToken()
610 if err != nil {
611 return nil, fmt.Errorf("failed to get SPT from client credentials: %v", err)
612 }
613 return autorest.NewBearerAuthorizer(spToken), nil
614 }
615 mtSPT, err := ccc.MultiTenantServicePrincipalToken()
616 if err != nil {
617 return nil, fmt.Errorf("failed to get multitenant SPT from client credentials: %v", err)
618 }
619 return autorest.NewMultiTenantServicePrincipalTokenAuthorizer(mtSPT), nil
620 }
621
622
623 type ClientCertificateConfig struct {
624 ClientID string
625 CertificatePath string
626 CertificatePassword string
627 TenantID string
628 AuxTenants []string
629 AADEndpoint string
630 Resource string
631 }
632
633
634 func (ccc ClientCertificateConfig) ServicePrincipalToken() (*adal.ServicePrincipalToken, error) {
635 oauthConfig, err := adal.NewOAuthConfig(ccc.AADEndpoint, ccc.TenantID)
636 if err != nil {
637 return nil, err
638 }
639 certData, err := ioutil.ReadFile(ccc.CertificatePath)
640 if err != nil {
641 return nil, fmt.Errorf("failed to read the certificate file (%s): %v", ccc.CertificatePath, err)
642 }
643 certificate, rsaPrivateKey, err := adal.DecodePfxCertificateData(certData, ccc.CertificatePassword)
644 if err != nil {
645 return nil, fmt.Errorf("failed to decode pkcs12 certificate while creating spt: %v", err)
646 }
647 return adal.NewServicePrincipalTokenFromCertificate(*oauthConfig, ccc.ClientID, certificate, rsaPrivateKey, ccc.Resource)
648 }
649
650
651 func (ccc ClientCertificateConfig) MultiTenantServicePrincipalToken() (*adal.MultiTenantServicePrincipalToken, error) {
652 oauthConfig, err := adal.NewMultiTenantOAuthConfig(ccc.AADEndpoint, ccc.TenantID, ccc.AuxTenants, adal.OAuthOptions{})
653 if err != nil {
654 return nil, err
655 }
656 certData, err := ioutil.ReadFile(ccc.CertificatePath)
657 if err != nil {
658 return nil, fmt.Errorf("failed to read the certificate file (%s): %v", ccc.CertificatePath, err)
659 }
660 certificate, rsaPrivateKey, err := adal.DecodePfxCertificateData(certData, ccc.CertificatePassword)
661 if err != nil {
662 return nil, fmt.Errorf("failed to decode pkcs12 certificate while creating spt: %v", err)
663 }
664 return adal.NewMultiTenantServicePrincipalTokenFromCertificate(oauthConfig, ccc.ClientID, certificate, rsaPrivateKey, ccc.Resource)
665 }
666
667
668 func (ccc ClientCertificateConfig) Authorizer() (autorest.Authorizer, error) {
669 if len(ccc.AuxTenants) == 0 {
670 spToken, err := ccc.ServicePrincipalToken()
671 if err != nil {
672 return nil, fmt.Errorf("failed to get oauth token from certificate auth: %v", err)
673 }
674 return autorest.NewBearerAuthorizer(spToken), nil
675 }
676 mtSPT, err := ccc.MultiTenantServicePrincipalToken()
677 if err != nil {
678 return nil, fmt.Errorf("failed to get multitenant SPT from certificate auth: %v", err)
679 }
680 return autorest.NewMultiTenantServicePrincipalTokenAuthorizer(mtSPT), nil
681 }
682
683
684 type DeviceFlowConfig struct {
685 ClientID string
686 TenantID string
687 AADEndpoint string
688 Resource string
689 }
690
691
692 func (dfc DeviceFlowConfig) Authorizer() (autorest.Authorizer, error) {
693 spToken, err := dfc.ServicePrincipalToken()
694 if err != nil {
695 return nil, fmt.Errorf("failed to get oauth token from device flow: %v", err)
696 }
697 return autorest.NewBearerAuthorizer(spToken), nil
698 }
699
700
701 func (dfc DeviceFlowConfig) ServicePrincipalToken() (*adal.ServicePrincipalToken, error) {
702 oauthConfig, err := adal.NewOAuthConfig(dfc.AADEndpoint, dfc.TenantID)
703 if err != nil {
704 return nil, err
705 }
706 oauthClient := &autorest.Client{}
707 deviceCode, err := adal.InitiateDeviceAuth(oauthClient, *oauthConfig, dfc.ClientID, dfc.Resource)
708 if err != nil {
709 return nil, fmt.Errorf("failed to start device auth flow: %s", err)
710 }
711 log.Println(*deviceCode.Message)
712 token, err := adal.WaitForUserCompletion(oauthClient, deviceCode)
713 if err != nil {
714 return nil, fmt.Errorf("failed to finish device auth flow: %s", err)
715 }
716 return adal.NewServicePrincipalTokenFromManualToken(*oauthConfig, dfc.ClientID, dfc.Resource, *token)
717 }
718
719
720 type UsernamePasswordConfig struct {
721 ClientID string
722 Username string
723 Password string
724 TenantID string
725 AADEndpoint string
726 Resource string
727 }
728
729
730 func (ups UsernamePasswordConfig) ServicePrincipalToken() (*adal.ServicePrincipalToken, error) {
731 oauthConfig, err := adal.NewOAuthConfig(ups.AADEndpoint, ups.TenantID)
732 if err != nil {
733 return nil, err
734 }
735 return adal.NewServicePrincipalTokenFromUsernamePassword(*oauthConfig, ups.ClientID, ups.Username, ups.Password, ups.Resource)
736 }
737
738
739 func (ups UsernamePasswordConfig) Authorizer() (autorest.Authorizer, error) {
740 spToken, err := ups.ServicePrincipalToken()
741 if err != nil {
742 return nil, fmt.Errorf("failed to get oauth token from username and password auth: %v", err)
743 }
744 return autorest.NewBearerAuthorizer(spToken), nil
745 }
746
747
748 type MSIConfig struct {
749 Resource string
750 ClientID string
751 }
752
753
754 func (mc MSIConfig) ServicePrincipalToken() (*adal.ServicePrincipalToken, error) {
755 spToken, err := adal.NewServicePrincipalTokenFromManagedIdentity(mc.Resource, &adal.ManagedIdentityOptions{
756 ClientID: mc.ClientID,
757 })
758 if err != nil {
759 return nil, fmt.Errorf("failed to get oauth token from MSI: %v", err)
760 }
761 return spToken, nil
762 }
763
764
765 func (mc MSIConfig) Authorizer() (autorest.Authorizer, error) {
766 spToken, err := mc.ServicePrincipalToken()
767 if err != nil {
768 return nil, err
769 }
770
771 return autorest.NewBearerAuthorizer(spToken), nil
772 }
773
View as plain text