Skip to content

Commit

Permalink
Use correct audience for MSAL Key Vault token #1566
Browse files Browse the repository at this point in the history
  • Loading branch information
thomas11 committed Mar 15, 2023
1 parent 4a9d3aa commit ecb9c69
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 29 deletions.
33 changes: 12 additions & 21 deletions provider/pkg/provider/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"strings"

"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/azure"
"github.com/hashicorp/go-azure-helpers/authentication"
"github.com/hashicorp/go-azure-helpers/sender"
"github.com/manicminer/hamilton/environments"
Expand Down Expand Up @@ -139,26 +138,29 @@ func runAzCmd(target interface{}, arg ...string) error {
return nil
}

func (k *azureNativeProvider) getAuthorizers(ctx context.Context, authConfig *authentication.Config) (tokenAuth autorest.Authorizer,
bearerAuth autorest.Authorizer, err error) {
type AuthorizerFactory func(api environments.Api) (autorest.Authorizer, error)

func (k *azureNativeProvider) makeAuthorizerFactories(ctx context.Context,
authConfig *authentication.Config) (AuthorizerFactory, AuthorizerFactory, error) {

buildSender := sender.BuildSender("AzureNative")

oauthConfig, err := k.buildOAuthConfig(authConfig)
if err != nil {
return nil, nil, err
}

api := k.autorestEnvToHamiltonEnv().ResourceManager

endpoint := k.environment.TokenAudience

tokenAuth, err = authConfig.GetMSALToken(ctx, api, buildSender, oauthConfig, endpoint)
if err != nil {
return nil, nil, err
tokenFactory := func(api environments.Api) (autorest.Authorizer, error) {
return authConfig.GetMSALToken(ctx, api, buildSender, oauthConfig, endpoint)
}

bearerAuth = authConfig.MSALBearerAuthorizerCallback(ctx, api, buildSender, oauthConfig, endpoint)
return tokenAuth, bearerAuth, nil
bearerAuthFactory := func(api environments.Api) (autorest.Authorizer, error) {
return authConfig.MSALBearerAuthorizerCallback(ctx, api, buildSender, oauthConfig, endpoint), nil
}

return tokenFactory, bearerAuthFactory, nil
}

func (k *azureNativeProvider) getOAuthToken(ctx context.Context, auth *authentication.Config, endpoint string) (string, error) {
Expand Down Expand Up @@ -208,14 +210,3 @@ func (k *azureNativeProvider) buildOAuthConfig(authConfig *authentication.Config
}
return oauthConfig, nil
}

func (k *azureNativeProvider) autorestEnvToHamiltonEnv() environments.Environment {
switch k.environment.Name {
case azure.USGovernmentCloud.Name:
return environments.USGovernmentL4
case azure.ChinaCloud.Name:
return environments.China
default:
return environments.Global
}
}
40 changes: 36 additions & 4 deletions provider/pkg/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"strings"
"time"

"github.com/manicminer/hamilton/environments"
"github.com/segmentio/encoding/json"

structpb "github.com/golang/protobuf/ptypes/struct"
Expand Down Expand Up @@ -176,19 +177,39 @@ func (k *azureNativeProvider) Configure(ctx context.Context,
}
k.environment = env

hamiltonEnv := k.autorestEnvToHamiltonEnv()

// The ctx Context given by gRPC is request-scoped and will be canceled after this request. We
// need the authorizers to function across requests.
authCtx := context.Background()
tokenAuth, bearerAuth, err := k.getAuthorizers(authCtx, authConfig)

tokenAuth, bearerAuth, err := k.makeAuthorizerFactories(authCtx, authConfig)
if err != nil {
return nil, fmt.Errorf("auth setup: %w", err)
}

resourceManagerAuth, err := tokenAuth(hamiltonEnv.ResourceManager)
if err != nil {
return nil, fmt.Errorf("building authorizer for %s: %w", hamiltonEnv.ResourceManager.Endpoint, err)
}

resourceManagerBearerAuth, err := bearerAuth(hamiltonEnv.ResourceManager)
if err != nil {
return nil, errors.Wrap(err, "building authorizer")
return nil, fmt.Errorf("building bearer authorizer for %s: %w", hamiltonEnv.ResourceManager.Endpoint, err)
}

keyVaultBearerAuth, err := tokenAuth(hamiltonEnv.KeyVault)
if err != nil {
return nil, fmt.Errorf("building authorizer for %s: %w", hamiltonEnv.KeyVault.Endpoint, err)
}

k.subscriptionID = authConfig.SubscriptionID
k.client.Authorizer = tokenAuth
k.client.Authorizer = resourceManagerAuth
k.client.UserAgent = k.getUserAgent()

k.customResources = resources.BuildCustomResources(&env, k.subscriptionID, bearerAuth, tokenAuth, k.client.UserAgent)
k.customResources = resources.BuildCustomResources(&env, k.subscriptionID,
resourceManagerBearerAuth, resourceManagerAuth, keyVaultBearerAuth,
k.client.UserAgent)

return &rpc.ConfigureResponse{
SupportsPreview: true,
Expand Down Expand Up @@ -1812,3 +1833,14 @@ func parseCheckpointObject(obj resource.PropertyMap) resource.PropertyMap {

return nil
}

func (k *azureNativeProvider) autorestEnvToHamiltonEnv() environments.Environment {
switch k.environment.Name {
case azure.USGovernmentCloud.Name:
return environments.USGovernmentL4
case azure.ChinaCloud.Name:
return environments.China
default:
return environments.Global
}
}
13 changes: 9 additions & 4 deletions provider/pkg/resources/customresources.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package resources

import (
"context"

"github.com/Azure/azure-sdk-for-go/services/keyvault/2016-10-01/keyvault"
"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2019-04-01/storage"
"github.com/Azure/go-autorest/autorest"
Expand Down Expand Up @@ -36,11 +37,15 @@ type CustomResource struct {
}

// BuildCustomResources creates a map of custom resources for given environment parameters.
func BuildCustomResources(env *azure.Environment, subscriptionID string, bearerAuth autorest.Authorizer,
tokenAuth autorest.Authorizer, userAgent string) map[string]*CustomResource {
func BuildCustomResources(env *azure.Environment,
subscriptionID string,
bearerAuth autorest.Authorizer,
tokenAuth autorest.Authorizer,
kvBearerAuth autorest.Authorizer,
userAgent string) map[string]*CustomResource {

kvClient := keyvault.New()
kvClient.Authorizer = bearerAuth
kvClient.Authorizer = kvBearerAuth
kvClient.UserAgent = userAgent

storageAccountsClient := storage.NewAccountsClientWithBaseURI(env.ResourceManagerEndpoint, subscriptionID)
Expand All @@ -64,7 +69,7 @@ func BuildCustomResources(env *azure.Environment, subscriptionID string, bearerA
}

// featureLookup is a map of custom resource to lookup their capabilities.
var featureLookup = BuildCustomResources(&azure.Environment{}, "", nil, nil, "")
var featureLookup = BuildCustomResources(&azure.Environment{}, "", nil, nil, nil, "")

// HasCustomDelete returns true if a custom DELETE operation is defined for a given API path.
func HasCustomDelete(path string) bool {
Expand Down

0 comments on commit ecb9c69

Please sign in to comment.