Skip to content

Commit

Permalink
Allow Bearer token authorization in VMC
Browse files Browse the repository at this point in the history
Currently, the token is passed to the proxy using CSP header. This
wouldn't work for direct VMC connections. A new provider attribute
is offered here to switch to Bearer token authorization. Default
behavior does not change.
  • Loading branch information
annakhm committed Dec 18, 2020
1 parent 5c7b61f commit 7b150f8
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 7 deletions.
45 changes: 38 additions & 7 deletions nsxt/provider.go
Expand Up @@ -28,6 +28,7 @@ var defaultRetryOnStatusCodes = []int{429, 503}
// Provider configuration that is shared for policy and MP
type commonProviderConfig struct {
RemoteAuth bool
BearerToken string
ToleratePartialSuccess bool
}

Expand Down Expand Up @@ -142,6 +143,13 @@ func Provider() *schema.Provider {
Description: "Long-living API token for VMC authorization",
DefaultFunc: schema.EnvDefaultFunc("NSXT_VMC_TOKEN", nil),
},
"vmc_auth_mode": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("NSXT_VMC_AUTH_MODE", "Default"),
ValidateFunc: validation.StringInSlice([]string{"Default", "Bearer"}, false),
Description: "Mode for VMC authorization",
},
"enforcement_point": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -556,6 +564,7 @@ func configurePolicyConnectorData(d *schema.ResourceData, clients *nsxtClients)
clientAuthDefined := (len(clientAuthCertFile) > 0) || (len(clientAuthCert) > 0)
policyEnforcementPoint := d.Get("enforcement_point").(string)
policyGlobalManager := d.Get("global_manager").(bool)
vmcAuthMode := d.Get("vmc_auth_mode").(string)

if host == "" {
return fmt.Errorf("host must be provided")
Expand All @@ -582,8 +591,13 @@ func configurePolicyConnectorData(d *schema.ResourceData, clients *nsxtClients)
return err
}

securityCtx.SetProperty(security.AUTHENTICATION_SCHEME_ID, security.OAUTH_SCHEME_ID)
securityCtx.SetProperty(security.ACCESS_TOKEN, apiToken)
if vmcAuthMode == "Bearer" {
clients.CommonConfig.BearerToken = apiToken
} else {

securityCtx.SetProperty(security.AUTHENTICATION_SCHEME_ID, security.OAUTH_SCHEME_ID)
securityCtx.SetProperty(security.ACCESS_TOKEN, apiToken)
}
} else {
if username == "" {
return fmt.Errorf("username must be provided")
Expand Down Expand Up @@ -621,20 +635,34 @@ func configurePolicyConnectorData(d *schema.ResourceData, clients *nsxtClients)
return nil
}

type remoteBasicAuthHeaderProcessor struct {
type remoteAuthHeaderProcessor struct {
}

func newRemoteBasicAuthHeaderProcessor() *remoteBasicAuthHeaderProcessor {
return &remoteBasicAuthHeaderProcessor{}
func newRemoteAuthHeaderProcessor() *remoteAuthHeaderProcessor {
return &remoteAuthHeaderProcessor{}
}

func (processor remoteBasicAuthHeaderProcessor) Process(req *http.Request) error {
func (processor remoteAuthHeaderProcessor) Process(req *http.Request) error {
oldAuthHeader := req.Header.Get("Authorization")
newAuthHeader := strings.Replace(oldAuthHeader, "Basic", "Remote", 1)
req.Header.Set("Authorization", newAuthHeader)
return nil
}

type bearerAuthHeaderProcessor struct {
Token string
}

func newBearerAuthHeaderProcessor(token string) *bearerAuthHeaderProcessor {
return &bearerAuthHeaderProcessor{Token: token}
}

func (processor bearerAuthHeaderProcessor) Process(req *http.Request) error {
newAuthHeader := fmt.Sprintf("Bearer %s", processor.Token)
req.Header.Set("Authorization", newAuthHeader)
return nil
}

func applyLicense(c *api.APIClient, licenseKey string) error {
if c == nil {
return fmt.Errorf("API client not configured")
Expand Down Expand Up @@ -704,7 +732,10 @@ func getPolicyConnector(clients interface{}) *client.RestConnector {
connector.SetSecurityContext(c.PolicySecurityContext)
}
if c.CommonConfig.RemoteAuth {
connector.AddRequestProcessor(newRemoteBasicAuthHeaderProcessor())
connector.AddRequestProcessor(newRemoteAuthHeaderProcessor())
}
if len(c.CommonConfig.BearerToken) > 0 {
connector.AddRequestProcessor(newBearerAuthHeaderProcessor(c.CommonConfig.BearerToken))
}

return connector
Expand Down
4 changes: 4 additions & 0 deletions website/docs/index.html.markdown
Expand Up @@ -192,6 +192,10 @@ The following arguments are used to configure the VMware NSX-T Provider:
* `vmc_auth_host` - (Optional) URL for VMC authorization service that is used
to obtain short-lived token for NSX manager access. Defaults to VMC
console authorization URL.
* `vmc_auth_mode` - (Optional) VMC authorization mode, that determines what HTTP
header is used for authorization. Accepted values are `Default`, `Bearer`. For
direct VMC connections, use `Bearer` mode, otherwise no need to specify this
setting.
* `enforcement_point` - (Optional) Enforcement point, mostly relevant for policy
data sources. For VMC environment, this should be set to `vmc-enforcementpoint`.
For on-prem deployments, this setting should not be specified.
Expand Down

0 comments on commit 7b150f8

Please sign in to comment.