diff --git a/authentication/auth_method_azure_cli_token.go b/authentication/auth_method_azure_cli_token.go index c35c1da..6e5b620 100644 --- a/authentication/auth_method_azure_cli_token.go +++ b/authentication/auth_method_azure_cli_token.go @@ -5,13 +5,17 @@ import ( "context" "encoding/json" "fmt" + "io/ioutil" + "os" "os/exec" + "path/filepath" "strings" "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/adal" "github.com/Azure/go-autorest/autorest/azure/cli" "github.com/hashicorp/go-multierror" + "github.com/mitchellh/go-homedir" ) type azureCliTokenAuth struct { @@ -161,6 +165,12 @@ func obtainAuthorizationToken(endpoint string, subscriptionId string) (*cli.Toke return nil, fmt.Errorf("Error parsing json result from the Azure CLI: %v", err) } + // Currently, Azure CLI does not return the refresh token. Try reading the refresh token from user's disk. + if token.RefreshToken == "" { + // Ignore any error here: we don't want to fail because of no access to the tokens file. + token.RefreshToken, _ = readRefreshTokenFromAccessTokensFile(token.AccessToken) + } + return &token, nil } @@ -193,3 +203,39 @@ func jsonUnmarshalAzCmd(i interface{}, arg ...string) error { return nil } + +func readRefreshTokenFromAccessTokensFile(accessToken string) (string, error) { + azureConfig := os.Getenv("AZURE_CONFIG_DIR") + if azureConfig == "" { + home, err := homedir.Dir() + if err != nil { + return "", err + } + azureConfig = filepath.Join(home, ".azure") + } + path := filepath.Join(azureConfig, "accessTokens.json") + + jsonFile, err := os.Open(path) + if err != nil { + return "", err + } + defer jsonFile.Close() + + bytes, err := ioutil.ReadAll(jsonFile) + if err != nil { + return "", err + } + + var tokens []cli.Token + if err := json.Unmarshal(bytes, &tokens); err != nil { + return "", err + } + + for _, value := range tokens { + if value.AccessToken == accessToken { + return value.RefreshToken, nil + } + } + + return "", nil +} diff --git a/go.mod b/go.mod index 9f51e49..e96be0a 100644 --- a/go.mod +++ b/go.mod @@ -9,5 +9,6 @@ require ( github.com/Azure/go-autorest/autorest/validation v0.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/hashicorp/go-multierror v1.0.0 + github.com/mitchellh/go-homedir v1.1.0 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 )