Skip to content

Commit

Permalink
Add key authorizer for event grid. (#243)
Browse files Browse the repository at this point in the history
Added type EventGridKeyAuthorizer for key authorization with an event
grid topic.
Fixed a race condition when auto-refreshing service principal tokens.
  • Loading branch information
jhendrixMSFT authored Jan 30, 2018
1 parent c2a6835 commit d4e6b95
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 9 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# CHANGELOG

## v9.9.0

### New Features

- Added EventGridKeyAuthorizer for key authorization with event grid topics.

### Bug Fixes

- Fixed race condition when auto-refreshing service principal tokens.

## v9.8.1

### Bug Fixes
Expand Down
29 changes: 20 additions & 9 deletions autorest/adal/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"net/url"
"strconv"
"strings"
"sync"
"time"

"github.com/Azure/go-autorest/autorest/date"
Expand Down Expand Up @@ -244,13 +245,14 @@ func (secret *ServicePrincipalCertificateSecret) SetAuthenticationValues(spt *Se
type ServicePrincipalToken struct {
Token

secret ServicePrincipalSecret
oauthConfig OAuthConfig
clientID string
resource string
autoRefresh bool
refreshWithin time.Duration
sender Sender
secret ServicePrincipalSecret
oauthConfig OAuthConfig
clientID string
resource string
autoRefresh bool
autoRefreshLock *sync.Mutex
refreshWithin time.Duration
sender Sender

refreshCallbacks []TokenRefreshCallback
}
Expand Down Expand Up @@ -282,6 +284,7 @@ func NewServicePrincipalTokenWithSecret(oauthConfig OAuthConfig, id string, reso
clientID: id,
resource: resource,
autoRefresh: true,
autoRefreshLock: &sync.Mutex{},
refreshWithin: defaultRefresh,
sender: &http.Client{},
refreshCallbacks: callbacks,
Expand Down Expand Up @@ -499,6 +502,7 @@ func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedI
secret: &ServicePrincipalMSISecret{},
resource: resource,
autoRefresh: true,
autoRefreshLock: &sync.Mutex{},
refreshWithin: defaultRefresh,
sender: &http.Client{},
refreshCallbacks: callbacks,
Expand Down Expand Up @@ -532,10 +536,15 @@ func newTokenRefreshError(message string, resp *http.Response) TokenRefreshError
}

// EnsureFresh will refresh the token if it will expire within the refresh window (as set by
// RefreshWithin) and autoRefresh flag is on.
// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use.
func (spt *ServicePrincipalToken) EnsureFresh() error {
if spt.autoRefresh && spt.WillExpireIn(spt.refreshWithin) {
return spt.Refresh()
// take the lock then check to see if the token was already refreshed
spt.autoRefreshLock.Lock()
defer spt.autoRefreshLock.Unlock()
if spt.WillExpireIn(spt.refreshWithin) {
return spt.Refresh()
}
}
return nil
}
Expand All @@ -554,11 +563,13 @@ func (spt *ServicePrincipalToken) InvokeRefreshCallbacks(token Token) error {
}

// Refresh obtains a fresh token for the Service Principal.
// This method is not safe for concurrent use and should be syncrhonized.
func (spt *ServicePrincipalToken) Refresh() error {
return spt.refreshInternal(spt.resource)
}

// RefreshExchange refreshes the token, but for a different resource.
// This method is not safe for concurrent use and should be syncrhonized.
func (spt *ServicePrincipalToken) RefreshExchange(resource string) error {
return spt.refreshInternal(resource)
}
Expand Down
19 changes: 19 additions & 0 deletions autorest/authorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,22 @@ func newBearerChallenge(resp *http.Response) (bc bearerChallenge, err error) {

return bc, err
}

// EventGridKeyAuthorizer implements authorization for event grid using key authentication.
type EventGridKeyAuthorizer struct {
topicKey string
}

// NewEventGridKeyAuthorizer creates a new EventGridKeyAuthorizer
// with the specified topic key.
func NewEventGridKeyAuthorizer(topicKey string) EventGridKeyAuthorizer {
return EventGridKeyAuthorizer{topicKey: topicKey}
}

// WithAuthorization returns a PrepareDecorator that adds the aeg-sas-key authentication header.
func (egta EventGridKeyAuthorizer) WithAuthorization() PrepareDecorator {
headers := map[string]interface{}{
"aeg-sas-key": egta.topicKey,
}
return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization()
}

0 comments on commit d4e6b95

Please sign in to comment.