[client] Consume the forced account prompt after the retry

forceAccountPrompt was never cleared, so a flow that outlived the retry it
was armed for kept sending prompt=login on every later authorization
request and re-authenticated the user each time. RequestAuthInfo now takes
the flag as it builds the request.
This commit is contained in:
Zoltán Papp
2026-08-27 11:33:55 +02:00
parent 3cd20882fa
commit 6fb1ad7d5a
2 changed files with 33 additions and 1 deletions
+7 -1
View File
@@ -154,9 +154,12 @@ func (p *PKCEAuthorizationFlow) RequestAuthInfo(ctx context.Context) (AuthFlowIn
oauth2.SetAuthURLParam("code_challenge", codeChallenge),
oauth2.SetAuthURLParam("audience", p.providerConfig.Audience),
}
forceAccountPrompt := p.forceAccountPrompt
p.forceAccountPrompt = false
if !p.providerConfig.DisablePromptLogin {
switch {
case p.forceAccountPrompt:
case forceAccountPrompt:
params = append(params, oauth2.SetAuthURLParam("prompt", "login"))
case p.providerConfig.LoginFlag == common.LoginFlagPromptLogin:
params = append(params, oauth2.SetAuthURLParam("prompt", "login"))
@@ -185,6 +188,9 @@ func (p *PKCEAuthorizationFlow) SetLoginHint(hint string) {
// re-authenticate instead of answering from the session it already holds. Used
// to retry a login that came back for an account other than the one hinted.
//
// The next RequestAuthInfo consumes the flag, so a flow that outlives its retry
// goes back to the configured behaviour instead of re-authenticating forever.
//
// DisablePromptLogin still wins: it is set for IdPs that break on prompt=login,
// where retrying with it would replace a wrong-account login with one that
// cannot complete at all.
+26
View File
@@ -76,6 +76,32 @@ func TestPromptLogin(t *testing.T) {
}
}
func TestForceAccountPromptAppliesOnlyToTheRetry(t *testing.T) {
config := PKCEAuthProviderConfig{
ClientID: "test-client-id",
Audience: "test-audience",
TokenEndpoint: "https://test-token-endpoint.com/token",
Scope: "openid email profile",
AuthorizationEndpoint: "https://test-auth-endpoint.com/authorize",
RedirectURLs: []string{"http://127.0.0.1:33992/"},
UseIDToken: true,
LoginFlag: mgm.LoginFlagNone,
}
pkce, err := NewPKCEAuthorizationFlow(config)
require.NoError(t, err)
pkce.ForceAccountPrompt()
retry, err := pkce.RequestAuthInfo(context.Background())
require.NoError(t, err)
require.Contains(t, retry.VerificationURIComplete, "prompt=login")
next, err := pkce.RequestAuthInfo(context.Background())
require.NoError(t, err)
require.NotContains(t, next.VerificationURIComplete, "prompt=login",
"the forced prompt outlived the retry it was armed for")
}
func TestIsPortInExcludedRange(t *testing.T) {
tests := []struct {
name string