func (mt *MultiTenantBearerAuthorizer) WithAuthorization() PrepareDecorator {
	return func(p Preparer) Preparer {
		return PreparerFunc(func(r *http.Request) (*http.Request, error) {
			r, err := p.Prepare(r)
			if err != nil {
				return r, err
			}
			if refresher, ok := mt.tp.(adal.RefresherWithContext); ok {
				err = refresher.EnsureFreshWithContext(r.Context())
				if err != nil {
					var resp *http.Response
					if tokError, ok := err.(adal.TokenRefreshError); ok {
						resp = tokError.Response()
					}
					return r, NewErrorWithError(err, "azure.multiTenantSPTAuthorizer", "WithAuthorization", resp,
						"Failed to refresh one or more Tokens for request to %s", r.URL)
				}
			}
			r, err = Prepare(r, WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", mt.tp.PrimaryOAuthToken())))
			if err != nil {
				return r, err
			}
			auxTokens := mt.tp.AuxiliaryOAuthTokens()
			for i := range auxTokens {
				auxTokens[i] = fmt.Sprintf("Bearer %s", auxTokens[i])
			}
			return Prepare(r, WithHeader(headerAuxAuthorization, strings.Join(auxTokens, ", ")))
		})
	}
}
WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header using the
primary token along with the auxiliary authorization header using the auxiliary tokens.

By default, the token will be automatically refreshed through the Refresher interface.
package autorest
import (
	"crypto/tls"
	"encoding/base64"
	"fmt"
	"net/http"
	"net/url"
	"strings"
	"github.com/Azure/go-autorest/autorest/adal"
)
const (
	bearerChallengeHeader       = "Www-Authenticate"
	bearer                      = "Bearer"
	tenantID                    = "tenantID"
	apiKeyAuthorizerHeader      = "Ocp-Apim-Subscription-Key"
	bingAPISdkHeader            = "X-BingApis-SDK-Client"
	golangBingAPISdkHeaderValue = "Go-SDK"
	authorization               = "Authorization"
	basic                       = "Basic"
)
type Authorizer interface {
	WithAuthorization() PrepareDecorator
}
type NullAuthorizer struct{}
func (na NullAuthorizer) WithAuthorization() PrepareDecorator {
	return WithNothing()
}
type APIKeyAuthorizer struct {
	headers         map[string]interface{}
	queryParameters map[string]interface{}
}
func NewAPIKeyAuthorizerWithHeaders(headers map[string]interface{}) *APIKeyAuthorizer {
	return NewAPIKeyAuthorizer(headers, nil)
}
func NewAPIKeyAuthorizerWithQueryParameters(queryParameters map[string]interface{}) *APIKeyAuthorizer {
	return NewAPIKeyAuthorizer(nil, queryParameters)
}
func NewAPIKeyAuthorizer(headers map[string]interface{}, queryParameters map[string]interface{}) *APIKeyAuthorizer {
	return &APIKeyAuthorizer{headers: headers, queryParameters: queryParameters}
}
func (aka *APIKeyAuthorizer) WithAuthorization() PrepareDecorator {
	return func(p Preparer) Preparer {
		return DecoratePreparer(p, WithHeaders(aka.headers), WithQueryParameters(aka.queryParameters))
	}
}
type CognitiveServicesAuthorizer struct {
	subscriptionKey string
}
func NewCognitiveServicesAuthorizer(subscriptionKey string) *CognitiveServicesAuthorizer {
	return &CognitiveServicesAuthorizer{subscriptionKey: subscriptionKey}
}
func (csa *CognitiveServicesAuthorizer) WithAuthorization() PrepareDecorator {
	headers := make(map[string]interface{})
	headers[apiKeyAuthorizerHeader] = csa.subscriptionKey
	headers[bingAPISdkHeader] = golangBingAPISdkHeaderValue
	return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization()
}
type BearerAuthorizer struct {
	tokenProvider adal.OAuthTokenProvider
}
func NewBearerAuthorizer(tp adal.OAuthTokenProvider) *BearerAuthorizer {
	return &BearerAuthorizer{tokenProvider: tp}
}
func (ba *BearerAuthorizer) WithAuthorization() PrepareDecorator {
	return func(p Preparer) Preparer {
		return PreparerFunc(func(r *http.Request) (*http.Request, error) {
			r, err := p.Prepare(r)
			if err == nil {
				if refresher, ok := ba.tokenProvider.(adal.RefresherWithContext); ok {
					err = refresher.EnsureFreshWithContext(r.Context())
				} else if refresher, ok := ba.tokenProvider.(adal.Refresher); ok {
					err = refresher.EnsureFresh()
				}
				if err != nil {
					var resp *http.Response
					if tokError, ok := err.(adal.TokenRefreshError); ok {
						resp = tokError.Response()
					}
					return r, NewErrorWithError(err, "azure.BearerAuthorizer", "WithAuthorization", resp,
						"Failed to refresh the Token for request to %s", r.URL)
				}
				return Prepare(r, WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", ba.tokenProvider.OAuthToken())))
			}
			return r, err
		})
	}
}
func (ba *BearerAuthorizer) TokenProvider() adal.OAuthTokenProvider {
	return ba.tokenProvider
}
type BearerAuthorizerCallbackFunc func(tenantID, resource string) (*BearerAuthorizer, error)
type BearerAuthorizerCallback struct {
	sender   Sender
	callback BearerAuthorizerCallbackFunc
}
func NewBearerAuthorizerCallback(s Sender, callback BearerAuthorizerCallbackFunc) *BearerAuthorizerCallback {
	if s == nil {
		s = sender(tls.RenegotiateNever)
	}
	return &BearerAuthorizerCallback{sender: s, callback: callback}
}
func (bacb *BearerAuthorizerCallback) WithAuthorization() PrepareDecorator {
	return func(p Preparer) Preparer {
		return PreparerFunc(func(r *http.Request) (*http.Request, error) {
			r, err := p.Prepare(r)
			if err == nil {
				rCopy := *r
				removeRequestBody(&rCopy)
				resp, err := bacb.sender.Do(&rCopy)
				if err != nil {
					return r, err
				}
				DrainResponseBody(resp)
				if resp.StatusCode == 401 && hasBearerChallenge(resp.Header) {
					bc, err := newBearerChallenge(resp.Header)
					if err != nil {
						return r, err
					}
					if bacb.callback != nil {
						ba, err := bacb.callback(bc.values[tenantID], bc.values["resource"])
						if err != nil {
							return r, err
						}
						return Prepare(r, ba.WithAuthorization())
					}
				}
			}
			return r, err
		})
	}
}
func hasBearerChallenge(header http.Header) bool {
	authHeader := header.Get(bearerChallengeHeader)
	if len(authHeader) == 0 || strings.Index(authHeader, bearer) < 0 {
		return false
	}
	return true
}
type bearerChallenge struct {
	values map[string]string
}
func newBearerChallenge(header http.Header) (bc bearerChallenge, err error) {
	challenge := strings.TrimSpace(header.Get(bearerChallengeHeader))
	trimmedChallenge := challenge[len(bearer)+1:]
	pairs := strings.Split(trimmedChallenge, ",")
	if len(pairs) < 1 {
		err = fmt.Errorf("challenge '%s' contains no pairs", challenge)
		return bc, err
	}
	bc.values = make(map[string]string)
	for i := range pairs {
		trimmedPair := strings.TrimSpace(pairs[i])
		pair := strings.Split(trimmedPair, "=")
		if len(pair) == 2 {
			key := strings.Trim(pair[0], "\"")
			value := strings.Trim(pair[1], "\"")
			switch key {
			case "authorization", "authorization_uri":
				asURL, err := url.Parse(value)
				if err != nil {
					return bc, err
				}
				bc.values[tenantID] = asURL.Path[1:]
			default:
				bc.values[key] = value
			}
		}
	}
	return bc, err
}
type EventGridKeyAuthorizer struct {
	topicKey string
}
func NewEventGridKeyAuthorizer(topicKey string) EventGridKeyAuthorizer {
	return EventGridKeyAuthorizer{topicKey: topicKey}
}
func (egta EventGridKeyAuthorizer) WithAuthorization() PrepareDecorator {
	headers := map[string]interface{}{
		"aeg-sas-key": egta.topicKey,
	}
	return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization()
}
type BasicAuthorizer struct {
	userName string
	password string
}
func NewBasicAuthorizer(userName, password string) *BasicAuthorizer {
	return &BasicAuthorizer{
		userName: userName,
		password: password,
	}
}
func (ba *BasicAuthorizer) WithAuthorization() PrepareDecorator {
	headers := make(map[string]interface{})
	headers[authorization] = basic + " " + base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", ba.userName, ba.password)))
	return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization()
}
type MultiTenantServicePrincipalTokenAuthorizer interface {
	WithAuthorization() PrepareDecorator
}
func NewMultiTenantServicePrincipalTokenAuthorizer(tp adal.MultitenantOAuthTokenProvider) MultiTenantServicePrincipalTokenAuthorizer {
	return NewMultiTenantBearerAuthorizer(tp)
}
type MultiTenantBearerAuthorizer struct {
	tp adal.MultitenantOAuthTokenProvider
}
func NewMultiTenantBearerAuthorizer(tp adal.MultitenantOAuthTokenProvider) *MultiTenantBearerAuthorizer {
	return &MultiTenantBearerAuthorizer{tp: tp}
}