-
Notifications
You must be signed in to change notification settings - Fork 10
AUT-1496 Re-authenticate instead of refresh-looping on session-capped token #149
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,20 +41,30 @@ export class SmartlingAuthApi extends SmartlingBaseApi implements AccessTokenPro | |
|
|
||
| this.logger.debug(`Refresh token with: ${JSON.stringify(this.response, SmartlingBaseApi.sensitiveReplacer)}`); | ||
|
|
||
| return await this.makeRequest( | ||
| const refreshedToken: AccessTokenDto = await this.makeRequest( | ||
| "post", | ||
| `${this.entrypoint}/authenticate/refresh`, | ||
| JSON.stringify({ | ||
| refreshToken: this.response.refreshToken | ||
| }) | ||
| ); | ||
|
|
||
| if (!this.isSessionCapped(refreshedToken)) { | ||
| return refreshedToken; | ||
| } | ||
|
|
||
| this.logger.debug(`Refreshed token has a session-capped lifetime (${refreshedToken.refreshExpiresIn}s); re-authenticating.`); | ||
| } | ||
|
|
||
| this.logger.debug(`Can't refresh, doing re-auth with: ${JSON.stringify(this.response, SmartlingBaseApi.sensitiveReplacer)}`); | ||
| this.logger.debug(`Falling back to re-auth with: ${JSON.stringify(this.response, SmartlingBaseApi.sensitiveReplacer)}`); | ||
|
|
||
| return await this.authenticate(); | ||
| } | ||
|
|
||
| isSessionCapped(response: AccessTokenDto): boolean { | ||
| return response.refreshExpiresIn > 0 && response.refreshExpiresIn < this.ttlCorrectionSec; | ||
| } | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion (non-blocking): In practice this self-heals: the same missing field makes Flagging as a judgment call rather than a fix: is the one-cycle exposure worth a
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed by combining with dimitrystd's offline-token point below:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Confirmed - Keycloak sets refresh_expires_in: 0 for offline-type tokens as a sentinel (governed by Offline Session Idle/Max, not the normal refresh TTL), not "already expired". Fixed with a Note: tokenCanBeRenewed() has the same refreshExpiresIn-arithmetic issue for the currently held token (computes requestTimestamp + 0 - ttlCorrectionSec, always in the past) - meaning offline-token clients today never even reach the refresh branch, they always full-authenticate(). That predates this PR and isn't in AUT-1496's scope, but worth a follow-up ticket if the MCP server work depends on offline tokens actually being refreshed rather than always re-authenticated. |
||
| resetRequestTimeStamp(): void { | ||
| this.requestTimestamp = this.time(); | ||
| } | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion (non-blocking): this debug line still reads
Can't refresh, doing re-auth with:on the new session-capped fallthrough path — but on that path the refresh call succeeded; it was discarded for being session-capped, not because refresh failed. During an incident, seeingRefreshed token has a session-capped lifetime (5s); re-authenticating.immediately followed byCan't refresh, doing re-auth with: {...}is contradictory and could send an on-call engineer down the wrong path (backend outage vs. expected Keycloak session-cap behavior).(Wording is just a suggestion — the point is decoupling this log from the specific "can't refresh" claim so it reads correctly on both the throw-based and session-capped fallback paths.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed - changed to "Falling back to re-auth with:" so it reads correctly on both the throw-based and session-capped fallback paths. In
a405df8.