diff --git a/cmd/start/start.go b/cmd/start/start.go index 5ed358086b..70f19b4e13 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -417,11 +417,11 @@ func startAPIs( } apis.RegisterHandlerOnPrefix(openapi.HandlerPrefix, openAPIHandler) - oidcProvider, err := oidc.NewProvider(config.OIDC, login.DefaultLoggedOutPath, config.ExternalSecure, commands, queries, authRepo, keys.OIDC, keys.OIDCKey, eventstore, dbClient, userAgentInterceptor, instanceInterceptor.Handler, limitingAccessInterceptor) + oidcServer, err := oidc.NewServer(config.OIDC, login.DefaultLoggedOutPath, config.ExternalSecure, commands, queries, authRepo, keys.OIDC, keys.OIDCKey, eventstore, dbClient, userAgentInterceptor, instanceInterceptor.Handler, limitingAccessInterceptor, config.Log.Slog()) if err != nil { return fmt.Errorf("unable to start oidc provider: %w", err) } - apis.RegisterHandlerPrefixes(oidcProvider.HttpHandler(), oidcPrefixes...) + apis.RegisterHandlerPrefixes(oidcServer, oidcPrefixes...) samlProvider, err := saml.NewProvider(config.SAML, config.ExternalSecure, commands, queries, authRepo, keys.OIDC, keys.SAML, eventstore, dbClient, instanceInterceptor.Handler, userAgentInterceptor, limitingAccessInterceptor) if err != nil { @@ -429,7 +429,7 @@ func startAPIs( } apis.RegisterHandlerOnPrefix(saml.HandlerPrefix, samlProvider.HttpHandler()) - c, err := console.Start(config.Console, config.ExternalSecure, oidcProvider.IssuerFromRequest, middleware.CallDurationHandler, instanceInterceptor.Handler, limitingAccessInterceptor, config.CustomerPortal) + c, err := console.Start(config.Console, config.ExternalSecure, oidcServer.IssuerFromRequest, middleware.CallDurationHandler, instanceInterceptor.Handler, limitingAccessInterceptor, config.CustomerPortal) if err != nil { return fmt.Errorf("unable to start console: %w", err) } @@ -442,11 +442,11 @@ func startAPIs( authRepo, store, console.HandlerPrefix+"/", - op.AuthCallbackURL(oidcProvider), + oidcServer.AuthCallbackURL(), provider.AuthCallbackURL(samlProvider), config.ExternalSecure, userAgentInterceptor, - op.NewIssuerInterceptor(oidcProvider.IssuerFromRequest).Handler, + op.NewIssuerInterceptor(oidcServer.IssuerFromRequest).Handler, provider.NewIssuerInterceptor(samlProvider.IssuerFromRequest).Handler, instanceInterceptor.Handler, assetsCache.Handler, @@ -463,7 +463,7 @@ func startAPIs( apis.HandleFunc(login.EndpointDeviceAuth, login.RedirectDeviceAuthToPrefix) // After OIDC provider so that the callback endpoint can be used - if err := apis.RegisterService(ctx, oidc_v2.CreateServer(commands, queries, oidcProvider, config.ExternalSecure)); err != nil { + if err := apis.RegisterService(ctx, oidc_v2.CreateServer(commands, queries, oidcServer, config.ExternalSecure)); err != nil { return err } // handle grpc at last to be able to handle the root, because grpc and gateway require a lot of different prefixes diff --git a/go.mod b/go.mod index 875f6bb0e8..aba6c7fa39 100644 --- a/go.mod +++ b/go.mod @@ -61,8 +61,8 @@ require ( github.com/stretchr/testify v1.8.4 github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203 github.com/ttacon/libphonenumber v1.2.1 - github.com/zitadel/logging v0.4.0 - github.com/zitadel/oidc/v3 v3.0.2 + github.com/zitadel/logging v0.5.0 + github.com/zitadel/oidc/v3 v3.1.1 github.com/zitadel/passwap v0.4.0 github.com/zitadel/saml v0.1.2 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.43.0 @@ -76,6 +76,7 @@ require ( go.opentelemetry.io/otel/sdk/metric v0.40.0 go.opentelemetry.io/otel/trace v1.19.0 golang.org/x/crypto v0.14.0 + golang.org/x/exp v0.0.0-20231006140011-7918f672742d golang.org/x/net v0.17.0 golang.org/x/oauth2 v0.13.0 golang.org/x/sync v0.3.0 @@ -110,7 +111,6 @@ require ( github.com/smartystreets/assertions v1.0.0 // indirect github.com/zenazn/goji v1.0.1 // indirect github.com/zitadel/schema v1.3.0 // indirect - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect ) diff --git a/go.sum b/go.sum index 018d31f9ef..74d2dcf168 100644 --- a/go.sum +++ b/go.sum @@ -881,10 +881,10 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zenazn/goji v1.0.1 h1:4lbD8Mx2h7IvloP7r2C0D6ltZP6Ufip8Hn0wmSK5LR8= github.com/zenazn/goji v1.0.1/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -github.com/zitadel/logging v0.4.0 h1:lRAIFgaRoJpLNbsL7jtIYHcMDoEJP9QZB4GqMfl4xaA= -github.com/zitadel/logging v0.4.0/go.mod h1:6uALRJawpkkuUPCkgzfgcPR3c2N908wqnOnIrRelUFc= -github.com/zitadel/oidc/v3 v3.0.2 h1:fw0EAjx8lIlDMJ54hDz2fWIhpW/Y13tW5gd1qWGqbr4= -github.com/zitadel/oidc/v3 v3.0.2/go.mod h1:ne9V9FHug4iUZDV42JirWVLHcbmwaxY8LnkcfekHgRg= +github.com/zitadel/logging v0.5.0 h1:Kunouvqse/efXy4UDvFw5s3vP+Z4AlHo3y8wF7stXHA= +github.com/zitadel/logging v0.5.0/go.mod h1:IzP5fzwFhzzyxHkSmfF8dsyqFsQRJLLcQmwhIBzlGsE= +github.com/zitadel/oidc/v3 v3.1.1 h1:6A4j2ynPGuduM0v74zOf27v7m7ehsDtNEWFMw2WZyVs= +github.com/zitadel/oidc/v3 v3.1.1/go.mod h1:ne9V9FHug4iUZDV42JirWVLHcbmwaxY8LnkcfekHgRg= github.com/zitadel/passwap v0.4.0 h1:cMaISx+Ve7ilgG7Q8xOli4Z6IWr8Gndss+jeBk5A3O0= github.com/zitadel/passwap v0.4.0/go.mod h1:yHaDM4A68yRkdic5BZ4iUNoc19hT+kYt8n1/Nz+I87g= github.com/zitadel/saml v0.1.2 h1:RICwNTuP2upX4A1sZ8iq1rv4/x3DhZHzFx1e5bTKoTo= @@ -981,8 +981,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= diff --git a/internal/api/grpc/oidc/v2/oidc.go b/internal/api/grpc/oidc/v2/oidc.go index 465303b98a..6ca77bb619 100644 --- a/internal/api/grpc/oidc/v2/oidc.go +++ b/internal/api/grpc/oidc/v2/oidc.go @@ -91,7 +91,7 @@ func (s *Server) failAuthRequest(ctx context.Context, authRequestID string, ae * return nil, err } authReq := &oidc.AuthRequestV2{CurrentAuthRequest: aar} - callback, err := oidc.CreateErrorCallbackURL(authReq, errorReasonToOIDC(ae.GetError()), ae.GetErrorDescription(), ae.GetErrorUri(), s.op) + callback, err := oidc.CreateErrorCallbackURL(authReq, errorReasonToOIDC(ae.GetError()), ae.GetErrorDescription(), ae.GetErrorUri(), s.op.Provider()) if err != nil { return nil, err } @@ -110,9 +110,9 @@ func (s *Server) linkSessionToAuthRequest(ctx context.Context, authRequestID str ctx = op.ContextWithIssuer(ctx, http.BuildOrigin(authz.GetInstance(ctx).RequestedHost(), s.externalSecure)) var callback string if aar.ResponseType == domain.OIDCResponseTypeCode { - callback, err = oidc.CreateCodeCallbackURL(ctx, authReq, s.op) + callback, err = oidc.CreateCodeCallbackURL(ctx, authReq, s.op.Provider()) } else { - callback, err = oidc.CreateTokenCallbackURL(ctx, authReq, s.op) + callback, err = oidc.CreateTokenCallbackURL(ctx, authReq, s.op.Provider()) } if err != nil { return nil, err diff --git a/internal/api/grpc/oidc/v2/server.go b/internal/api/grpc/oidc/v2/server.go index 823594fbd0..7595ae927e 100644 --- a/internal/api/grpc/oidc/v2/server.go +++ b/internal/api/grpc/oidc/v2/server.go @@ -1,11 +1,11 @@ package oidc import ( - "github.com/zitadel/oidc/v3/pkg/op" "google.golang.org/grpc" "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/api/grpc/server" + "github.com/zitadel/zitadel/internal/api/oidc" "github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/query" oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2beta" @@ -18,7 +18,7 @@ type Server struct { command *command.Commands query *query.Queries - op op.OpenIDProvider + op *oidc.Server externalSecure bool } @@ -27,7 +27,7 @@ type Config struct{} func CreateServer( command *command.Commands, query *query.Queries, - op op.OpenIDProvider, + op *oidc.Server, externalSecure bool, ) *Server { return &Server{ diff --git a/internal/api/oidc/op.go b/internal/api/oidc/op.go index c165b117b9..117172a440 100644 --- a/internal/api/oidc/op.go +++ b/internal/api/oidc/op.go @@ -9,6 +9,7 @@ import ( "github.com/rakyll/statik/fs" "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/oidc/v3/pkg/op" + "golang.org/x/exp/slog" "golang.org/x/text/language" "github.com/zitadel/zitadel/internal/api/assets" @@ -80,7 +81,7 @@ type OPStorage struct { assetAPIPrefix func(ctx context.Context) string } -func NewProvider( +func NewServer( config Config, defaultLogoutRedirectURI string, externalSecure bool, @@ -93,19 +94,17 @@ func NewProvider( projections *database.DB, userAgentCookie, instanceHandler func(http.Handler) http.Handler, accessHandler *middleware.AccessInterceptor, -) (op.OpenIDProvider, error) { + fallbackLogger *slog.Logger, +) (*Server, error) { opConfig, err := createOPConfig(config, defaultLogoutRedirectURI, cryptoKey) if err != nil { return nil, caos_errs.ThrowInternal(err, "OIDC-EGrqd", "cannot create op config: %w") } storage := newStorage(config, command, query, repo, encryptionAlg, es, projections, externalSecure) - options, err := createOptions( - config, - externalSecure, - userAgentCookie, - instanceHandler, - accessHandler.HandleIgnorePathPrefixes(ignoredQuotaLimitEndpoint(config.CustomEndpoints)), - ) + var options []op.Option + if !externalSecure { + options = append(options, op.WithAllowInsecure()) + } if err != nil { return nil, caos_errs.ThrowInternal(err, "OIDC-D3gq1", "cannot create options: %w") } @@ -118,7 +117,22 @@ func NewProvider( if err != nil { return nil, caos_errs.ThrowInternal(err, "OIDC-DAtg3", "cannot create provider") } - return provider, nil + + server := &Server{ + LegacyServer: op.NewLegacyServer(provider, endpoints(config.CustomEndpoints)), + } + metricTypes := []metrics.MetricType{metrics.MetricTypeRequestCount, metrics.MetricTypeStatusCode, metrics.MetricTypeTotalCount} + server.Handler = op.RegisterLegacyServer(server, op.WithHTTPMiddleware( + middleware.MetricsHandler(metricTypes), + middleware.TelemetryHandler(), + middleware.NoCacheInterceptor().Handler, + instanceHandler, + userAgentCookie, + http_utils.CopyHeadersToContext, + accessHandler.HandleIgnorePathPrefixes(ignoredQuotaLimitEndpoint(config.CustomEndpoints)), + )) + + return server, nil } func ignoredQuotaLimitEndpoint(endpoints *EndpointConfig) []string { @@ -158,61 +172,6 @@ func createOPConfig(config Config, defaultLogoutRedirectURI string, cryptoKey [] return opConfig, nil } -func createOptions(config Config, externalSecure bool, userAgentCookie, instanceHandler, accessHandler func(http.Handler) http.Handler) ([]op.Option, error) { - metricTypes := []metrics.MetricType{metrics.MetricTypeRequestCount, metrics.MetricTypeStatusCode, metrics.MetricTypeTotalCount} - options := []op.Option{ - op.WithHttpInterceptors( - middleware.MetricsHandler(metricTypes), - middleware.TelemetryHandler(), - middleware.NoCacheInterceptor().Handler, - instanceHandler, - userAgentCookie, - http_utils.CopyHeadersToContext, - accessHandler, - ), - } - if !externalSecure { - options = append(options, op.WithAllowInsecure()) - } - endpoints := customEndpoints(config.CustomEndpoints) - if len(endpoints) != 0 { - options = append(options, endpoints...) - } - return options, nil -} - -func customEndpoints(endpointConfig *EndpointConfig) []op.Option { - if endpointConfig == nil { - return nil - } - options := []op.Option{} - if endpointConfig.Auth != nil { - options = append(options, op.WithCustomAuthEndpoint(op.NewEndpointWithURL(endpointConfig.Auth.Path, endpointConfig.Auth.URL))) - } - if endpointConfig.Token != nil { - options = append(options, op.WithCustomTokenEndpoint(op.NewEndpointWithURL(endpointConfig.Token.Path, endpointConfig.Token.URL))) - } - if endpointConfig.Introspection != nil { - options = append(options, op.WithCustomIntrospectionEndpoint(op.NewEndpointWithURL(endpointConfig.Introspection.Path, endpointConfig.Introspection.URL))) - } - if endpointConfig.Userinfo != nil { - options = append(options, op.WithCustomUserinfoEndpoint(op.NewEndpointWithURL(endpointConfig.Userinfo.Path, endpointConfig.Userinfo.URL))) - } - if endpointConfig.Revocation != nil { - options = append(options, op.WithCustomRevocationEndpoint(op.NewEndpointWithURL(endpointConfig.Revocation.Path, endpointConfig.Revocation.URL))) - } - if endpointConfig.EndSession != nil { - options = append(options, op.WithCustomEndSessionEndpoint(op.NewEndpointWithURL(endpointConfig.EndSession.Path, endpointConfig.EndSession.URL))) - } - if endpointConfig.Keys != nil { - options = append(options, op.WithCustomKeysEndpoint(op.NewEndpointWithURL(endpointConfig.Keys.Path, endpointConfig.Keys.URL))) - } - if endpointConfig.DeviceAuth != nil { - options = append(options, op.WithCustomDeviceAuthorizationEndpoint(op.NewEndpointWithURL(endpointConfig.DeviceAuth.Path, endpointConfig.DeviceAuth.URL))) - } - return options -} - func newStorage(config Config, command *command.Commands, query *query.Queries, repo repository.Repository, encAlg crypto.EncryptionAlgorithm, es *eventstore.Eventstore, db *database.DB, externalSecure bool) *OPStorage { return &OPStorage{ repo: repo, diff --git a/internal/api/oidc/server.go b/internal/api/oidc/server.go new file mode 100644 index 0000000000..f9a38a2613 --- /dev/null +++ b/internal/api/oidc/server.go @@ -0,0 +1,188 @@ +package oidc + +import ( + "context" + "net/http" + + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/op" + "github.com/zitadel/zitadel/internal/telemetry/tracing" +) + +type Server struct { + http.Handler + *op.LegacyServer +} + +func endpoints(endpointConfig *EndpointConfig) op.Endpoints { + // some defaults. The new Server will disable enpoints that are nil. + endpoints := op.Endpoints{ + Authorization: op.NewEndpoint("/oauth/v2/authorize"), + Token: op.NewEndpoint("/oauth/v2/token"), + Introspection: op.NewEndpoint("/oauth/v2/introspect"), + Userinfo: op.NewEndpoint("/oidc/v1/userinfo"), + Revocation: op.NewEndpoint("/oauth/v2/revoke"), + EndSession: op.NewEndpoint("/oidc/v1/end_session"), + JwksURI: op.NewEndpoint("/oauth/v2/keys"), + DeviceAuthorization: op.NewEndpoint("/oauth/v2/device_authorization"), + } + + if endpointConfig == nil { + return endpoints + } + if endpointConfig.Auth != nil { + endpoints.Authorization = op.NewEndpointWithURL(endpointConfig.Auth.Path, endpointConfig.Auth.URL) + } + if endpointConfig.Token != nil { + endpoints.Token = op.NewEndpointWithURL(endpointConfig.Token.Path, endpointConfig.Token.URL) + } + if endpointConfig.Introspection != nil { + endpoints.Introspection = op.NewEndpointWithURL(endpointConfig.Introspection.Path, endpointConfig.Introspection.URL) + } + if endpointConfig.Userinfo != nil { + endpoints.Userinfo = op.NewEndpointWithURL(endpointConfig.Userinfo.Path, endpointConfig.Userinfo.URL) + } + if endpointConfig.Revocation != nil { + endpoints.Revocation = op.NewEndpointWithURL(endpointConfig.Revocation.Path, endpointConfig.Revocation.URL) + } + if endpointConfig.EndSession != nil { + endpoints.EndSession = op.NewEndpointWithURL(endpointConfig.EndSession.Path, endpointConfig.EndSession.URL) + } + if endpointConfig.Keys != nil { + endpoints.JwksURI = op.NewEndpointWithURL(endpointConfig.Keys.Path, endpointConfig.Keys.URL) + } + if endpointConfig.DeviceAuth != nil { + endpoints.DeviceAuthorization = op.NewEndpointWithURL(endpointConfig.DeviceAuth.Path, endpointConfig.DeviceAuth.URL) + } + return endpoints +} + +func (s *Server) IssuerFromRequest(r *http.Request) string { + return s.Provider().IssuerFromRequest(r) +} + +func (s *Server) Health(ctx context.Context, r *op.Request[struct{}]) (_ *op.Response, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + return s.LegacyServer.Health(ctx, r) +} + +func (s *Server) Ready(ctx context.Context, r *op.Request[struct{}]) (_ *op.Response, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + return s.LegacyServer.Ready(ctx, r) +} + +func (s *Server) Discovery(ctx context.Context, r *op.Request[struct{}]) (_ *op.Response, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + return s.LegacyServer.Discovery(ctx, r) +} + +func (s *Server) Keys(ctx context.Context, r *op.Request[struct{}]) (_ *op.Response, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + return s.LegacyServer.Keys(ctx, r) +} + +func (s *Server) VerifyAuthRequest(ctx context.Context, r *op.Request[oidc.AuthRequest]) (_ *op.ClientRequest[oidc.AuthRequest], err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + return s.LegacyServer.VerifyAuthRequest(ctx, r) +} + +func (s *Server) Authorize(ctx context.Context, r *op.ClientRequest[oidc.AuthRequest]) (_ *op.Redirect, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + return s.LegacyServer.Authorize(ctx, r) +} + +func (s *Server) DeviceAuthorization(ctx context.Context, r *op.ClientRequest[oidc.DeviceAuthorizationRequest]) (_ *op.Response, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + return s.LegacyServer.DeviceAuthorization(ctx, r) +} + +func (s *Server) VerifyClient(ctx context.Context, r *op.Request[op.ClientCredentials]) (_ op.Client, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + return s.LegacyServer.VerifyClient(ctx, r) +} + +func (s *Server) CodeExchange(ctx context.Context, r *op.ClientRequest[oidc.AccessTokenRequest]) (_ *op.Response, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + return s.LegacyServer.CodeExchange(ctx, r) +} + +func (s *Server) RefreshToken(ctx context.Context, r *op.ClientRequest[oidc.RefreshTokenRequest]) (_ *op.Response, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + return s.LegacyServer.RefreshToken(ctx, r) +} + +func (s *Server) JWTProfile(ctx context.Context, r *op.Request[oidc.JWTProfileGrantRequest]) (_ *op.Response, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + return s.LegacyServer.JWTProfile(ctx, r) +} + +func (s *Server) TokenExchange(ctx context.Context, r *op.ClientRequest[oidc.TokenExchangeRequest]) (_ *op.Response, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + return s.LegacyServer.TokenExchange(ctx, r) +} + +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) }() + + return s.LegacyServer.ClientCredentialsExchange(ctx, r) +} + +func (s *Server) DeviceToken(ctx context.Context, r *op.ClientRequest[oidc.DeviceAccessTokenRequest]) (_ *op.Response, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + return s.LegacyServer.DeviceToken(ctx, r) +} + +func (s *Server) Introspect(ctx context.Context, r *op.Request[op.IntrospectionRequest]) (_ *op.Response, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + return s.LegacyServer.Introspect(ctx, r) +} + +func (s *Server) UserInfo(ctx context.Context, r *op.Request[oidc.UserInfoRequest]) (_ *op.Response, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + return s.LegacyServer.UserInfo(ctx, r) +} + +func (s *Server) Revocation(ctx context.Context, r *op.ClientRequest[oidc.RevocationRequest]) (_ *op.Response, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + return s.LegacyServer.Revocation(ctx, r) +} + +func (s *Server) EndSession(ctx context.Context, r *op.Request[oidc.EndSessionRequest]) (_ *op.Redirect, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + return s.LegacyServer.EndSession(ctx, r) +}