-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
auth: Use a custom function to determine access token expiry
The default method `*oauth2.Token{}.Valid()` has a hardcoded delta of 10 seconds, which means that tokens are only renewed 10 seconds before they expire. This leads to race conditions during long running operations with the Resource Manager API, when a polling request is built immediately prior to this window, but only sent on or after the expiry time. Additionally, it's plausible that 1 (or more) second(s) may be lost during the process of token issuance, since it's likely the token is generated prior to being returned by the API, and it is the latter that informs us of the expiry time. This change extends this window to 10 minutes for any access token with a validity period of 20+ minutes. For tokens having a validity period less than 20 minutes, those are renewed when 50% or more of that validity period has elapsed. For example, a token that is valid for 1 hour (very common) will be renewed after it has been held for 50 minutes. However, a token issued for 10 minutes will be renewed when it has been held for 5 minutes (i.e. >=50% of the validity period).
- Loading branch information
1 parent
c1de4f8
commit d1a39ca
Showing
4 changed files
with
51 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package auth | ||
|
||
import ( | ||
"golang.org/x/oauth2" | ||
"time" | ||
|
||
"github.com/hashicorp/go-azure-sdk/sdk/claims" | ||
) | ||
|
||
const tokenExpiryDelta = 10 * time.Minute | ||
|
||
// tokenExpiresSoon returns true if the token expires within 10 minutes, or if more than 50% of its validity period has elapsed (if this can be determined), whichever is later | ||
func tokenDueForRenewal(token *oauth2.Token) bool { | ||
if token == nil { | ||
return true | ||
} | ||
|
||
// Some tokens may never expire | ||
if token.Expiry.IsZero() { | ||
return false | ||
} | ||
|
||
expiry := token.Expiry.Round(0) | ||
delta := tokenExpiryDelta | ||
now := time.Now() | ||
expiresWithinTenMinutes := expiry.Add(-delta).Before(now) | ||
|
||
// Try to parse the token claims to retrieve the issuedAt time | ||
if claims, err := claims.ParseClaims(token); err != nil { | ||
if claims.IssuedAt > 0 { | ||
issued := time.Unix(claims.IssuedAt, 0) | ||
validity := expiry.Sub(issued) | ||
|
||
// If the validity period is less than double the expiry delta, then instead | ||
// determine whether >50% of the validity period has elapsed | ||
if validity < delta*2 { | ||
halfValidityHasElapsed := issued.Add(validity / 2).Before(now) | ||
return halfValidityHasElapsed | ||
} | ||
} | ||
} | ||
|
||
return expiresWithinTenMinutes | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters