fix(coderd): support string type for oidc response's expires_in json property (#20152)

Some versions of Azure AD return expires_in property as string. Use
json.Number to accept either integer or string and then convert to
int64.
Helpful links:

https://learn.microsoft.com/en-us/answers/questions/2337020/azure-ad-token-endpoint-returns-expires-in-as-stri

https://feedback.azure.com/d365community/idea/7772fd95-26e6-ec11-a81b-0022484ee92d
This commit is contained in:
yyefimov
2025-10-15 13:37:37 -04:00
committed by GitHub
parent 91d4f8b59b
commit 1c8ee5cb88
+10 -4
View File
@@ -222,8 +222,9 @@ func (src *jwtTokenSource) Token() (*oauth2.Token, error) {
RefreshToken string `json:"refresh_token,omitempty"`
// Extra fields returned by the refresh that are needed
IDToken string `json:"id_token"`
ExpiresIn int64 `json:"expires_in"` // relative seconds from now
IDToken string `json:"id_token"`
ExpiresIn json.Number `json:"expires_in"` // relative seconds from now, use Number since Azure AD might return string
// error fields
// https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
ErrorCode string `json:"error"`
@@ -256,8 +257,13 @@ func (src *jwtTokenSource) Token() (*oauth2.Token, error) {
RefreshToken: tokenRes.RefreshToken,
}
if secs := tokenRes.ExpiresIn; secs > 0 {
newToken.Expiry = time.Now().Add(time.Duration(secs) * time.Second)
expiresIn, convertErr := tokenRes.ExpiresIn.Int64()
if convertErr != nil {
return nil, xerrors.Errorf("oauth2: cannot convert expires_in to int64: %w", convertErr)
}
if expiresIn > 0 {
newToken.Expiry = time.Now().Add(time.Duration(expiresIn) * time.Second)
}
// ID token is a JWT token. We can decode it to get the expiry.