zitadel/internal/api/oidc/token_client_credentials.go
Tim Möhlmann e879f90f38
fix(oidc): do not return access token for response type id_token (#8777)
# Which Problems Are Solved

Do not return an access token for implicit flow from v1 login, if the
`response_type` is `id_token`

# How the Problems Are Solved

Do not create the access token event if if the `response_type` is
`id_token`.

# Additional Changes

Token endpoint calls without auth request, such as machine users, token
exchange and refresh token, do not have a `response_type`. For such
calls the `OIDCResponseTypeUnspecified` enum is added at a `-1` offset,
in order not to break existing client configs.

# Additional Context

- https://discord.com/channels/927474939156643850/1294001717725237298
- Fixes https://github.com/zitadel/zitadel/issues/8776

(cherry picked from commit 778b4041ca)
2024-11-15 09:33:18 +01:00

58 lines
1.4 KiB
Go

package oidc
import (
"context"
"time"
"github.com/zitadel/oidc/v3/pkg/oidc"
"github.com/zitadel/oidc/v3/pkg/op"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/telemetry/tracing"
"github.com/zitadel/zitadel/internal/zerrors"
)
func (s *Server) ClientCredentialsExchange(ctx context.Context, r *op.ClientRequest[oidc.ClientCredentialsRequest]) (_ *op.Response, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() {
span.EndWithError(err)
err = oidcError(err)
}()
client, ok := r.Client.(*clientCredentialsClient)
if !ok {
return nil, zerrors.ThrowInternal(nil, "OIDC-ga0EP", "Error.Internal")
}
scope, err := op.ValidateAuthReqScopes(client, r.Data.Scope)
if err != nil {
return nil, err
}
scope, err = s.checkOrgScopes(ctx, client.resourceOwner, scope)
if err != nil {
return nil, err
}
session, err := s.command.CreateOIDCSession(ctx,
client.userID,
client.resourceOwner,
client.clientID,
"", // backChannelLogoutURI not needed for service user session
scope,
domain.AddAudScopeToAudience(ctx, nil, r.Data.Scope),
[]domain.UserAuthMethodType{domain.UserAuthMethodTypePassword},
time.Now(),
"",
nil,
nil,
domain.TokenReasonClientCredentials,
nil,
false,
"",
domain.OIDCResponseTypeUnspecified,
)
if err != nil {
return nil, err
}
return response(s.accessTokenResponseFromSession(ctx, client, session, "", "", false, true, true, false))
}