1
0
mirror of https://github.com/zitadel/zitadel.git synced 2024-12-14 03:54:21 +00:00

fix(oidc): only return state in access token response for implicit flow ()

# Which Problems Are Solved

Introduced with  the access token response incorrectly returned the
`state` parameter.

# How the Problems Are Solved

The `state` will only be returned for access token responses in an
implicit_flow.

# Additional Changes

None.

# Additional Context

- relates to  
- relates to
https://github.com/zitadel/oidc/issues/446#issuecomment-2144999644
- backport to 2.53.x

---------

Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
This commit is contained in:
Livio Spring 2024-06-12 13:53:56 +02:00 committed by GitHub
parent f4d32d98d3
commit fb95f4a8a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 12 additions and 10 deletions

View File

@ -528,6 +528,9 @@ func assertTokens(t *testing.T, tokens *oidc.Tokens[*oidc.IDTokenClaims], requir
} else {
assert.Empty(t, tokens.RefreshToken)
}
// since we test implicit flow directly, we can check that any token response must not
// return a `state` in the response
assert.Empty(t, tokens.Extra("state"))
}
func assertIDTokenClaims(t *testing.T, claims *oidc.IDTokenClaims, userID string, arm []string, sessionStart, sessionChange time.Time, sessionID string) {

View File

@ -34,41 +34,40 @@ func (s *Server) CodeExchange(ctx context.Context, r *op.ClientRequest[oidc.Acce
var (
session *command.OIDCSession
state string
)
if strings.HasPrefix(plainCode, command.IDPrefixV2) {
session, state, err = s.command.CreateOIDCSessionFromAuthRequest(
session, _, err = s.command.CreateOIDCSessionFromAuthRequest(
setContextUserSystem(ctx),
plainCode,
codeExchangeComplianceChecker(client, r.Data),
slices.Contains(client.GrantTypes(), oidc.GrantTypeRefreshToken),
)
} else {
session, state, err = s.codeExchangeV1(ctx, client, r.Data, r.Data.Code)
session, err = s.codeExchangeV1(ctx, client, r.Data, r.Data.Code)
}
if err != nil {
return nil, err
}
return response(s.accessTokenResponseFromSession(ctx, client, session, state, client.client.ProjectID, client.client.ProjectRoleAssertion, client.client.AccessTokenRoleAssertion, client.client.IDTokenRoleAssertion, client.client.IDTokenUserinfoAssertion))
return response(s.accessTokenResponseFromSession(ctx, client, session, "", client.client.ProjectID, client.client.ProjectRoleAssertion, client.client.AccessTokenRoleAssertion, client.client.IDTokenRoleAssertion, client.client.IDTokenUserinfoAssertion))
}
// codeExchangeV1 creates a v2 token from a v1 auth request.
func (s *Server) codeExchangeV1(ctx context.Context, client *Client, req *oidc.AccessTokenRequest, code string) (session *command.OIDCSession, state string, err error) {
func (s *Server) codeExchangeV1(ctx context.Context, client *Client, req *oidc.AccessTokenRequest, code string) (session *command.OIDCSession, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
authReq, err := s.getAuthRequestV1ByCode(ctx, code)
if err != nil {
return nil, "", err
return nil, err
}
if challenge := authReq.GetCodeChallenge(); challenge != nil || client.AuthMethod() == oidc.AuthMethodNone {
if err = op.AuthorizeCodeChallenge(req.CodeVerifier, challenge); err != nil {
return nil, "", err
return nil, err
}
}
if req.RedirectURI != authReq.GetRedirectURI() {
return nil, "", oidc.ErrInvalidGrant().WithDescription("redirect_uri does not correspond")
return nil, oidc.ErrInvalidGrant().WithDescription("redirect_uri does not correspond")
}
scope := authReq.GetScopes()
@ -88,9 +87,9 @@ func (s *Server) codeExchangeV1(ctx context.Context, client *Client, req *oidc.A
slices.Contains(scope, oidc.ScopeOfflineAccess),
)
if err != nil {
return nil, "", err
return nil, err
}
return session, authReq.TransferState, s.repo.DeleteAuthRequest(ctx, authReq.ID)
return session, s.repo.DeleteAuthRequest(ctx, authReq.ID)
}
// getAuthRequestV1ByCode finds the v1 auth request by code.