MCPcopy
hub / github.com/googleapis/mcp-toolbox / validateOpaqueToken

Method validateOpaqueToken

internal/auth/generic/generic.go:343–472  ·  view source on GitHub ↗

validateOpaqueToken validates an opaque token by calling the introspection endpoint

(ctx context.Context, tokenStr string)

Source from the content-addressed store, hash-verified

341
342// validateOpaqueToken validates an opaque token by calling the introspection endpoint
343func (a AuthService) validateOpaqueToken(ctx context.Context, tokenStr string) (map[string]any, error) {
344 logger, err := util.LoggerFromContext(ctx)
345 if err != nil {
346 return nil, fmt.Errorf("failed to get logger from context: %w", err)
347 }
348
349 introspectionURL := a.introspectionURL
350 if introspectionURL == "" {
351 introspectionURL, err = url.JoinPath(a.AuthorizationServer, "introspect")
352 if err != nil {
353 return nil, fmt.Errorf("failed to construct introspection URL: %w", err)
354 }
355 }
356
357 paramName := a.IntrospectionParamName
358 if paramName == "" {
359 paramName = "token"
360 }
361
362 var req *http.Request
363 if a.IntrospectionMethod == "GET" {
364 u, err := url.Parse(introspectionURL)
365 if err != nil {
366 return nil, fmt.Errorf("failed to parse introspection URL: %w", err)
367 }
368 q := u.Query()
369 q.Set(paramName, tokenStr)
370 u.RawQuery = q.Encode()
371 req, err = http.NewRequestWithContext(ctx, "GET", u.String(), nil)
372 if err != nil {
373 return nil, fmt.Errorf("failed to create introspection request: %w", err)
374 }
375 } else {
376 data := url.Values{}
377 data.Set(paramName, tokenStr)
378 req, err = http.NewRequestWithContext(ctx, "POST", introspectionURL, strings.NewReader(data.Encode()))
379 if err != nil {
380 return nil, fmt.Errorf("failed to create introspection request: %w", err)
381 }
382 req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
383 }
384 req.Header.Set("Accept", "application/json")
385
386 // Send request to auth server's introspection endpoint
387 resp, err := a.client.Do(req)
388 if err != nil {
389 logger.ErrorContext(ctx, "failed to call introspection endpoint: %v", err)
390 return nil, &MCPAuthError{Code: http.StatusInternalServerError, Message: fmt.Sprintf("failed to call introspection endpoint: %v", err), ScopesRequired: a.ScopesRequired}
391 }
392 defer resp.Body.Close()
393
394 if resp.StatusCode != http.StatusOK {
395 logger.WarnContext(ctx, "introspection failed with status: %d", resp.StatusCode)
396 return nil, &MCPAuthError{Code: http.StatusUnauthorized, Message: fmt.Sprintf("introspection failed with status: %d", resp.StatusCode), ScopesRequired: a.ScopesRequired}
397 }
398
399 body, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20))
400 if err != nil {

Callers 2

TestValidateOpaqueTokenFunction · 0.95
ValidateMCPAuthMethod · 0.95

Implementers 4

AuthServiceinternal/auth/google/google.go
AuthServiceinternal/auth/generic/generic.go
mockClashAuthServiceinternal/server/server_test.go
mockAuthServiceinternal/server/mcp/util/auth_test.go

Calls 12

validateClaimsMethod · 0.95
LoggerFromContextFunction · 0.92
DoMethod · 0.80
UnmarshalMethod · 0.80
ParseMethod · 0.65
QueryMethod · 0.65
SetMethod · 0.65
StringMethod · 0.65
ErrorContextMethod · 0.65
WarnContextMethod · 0.65
InfoContextMethod · 0.65
CloseMethod · 0.45

Tested by 1

TestValidateOpaqueTokenFunction · 0.76