handler

package
v0.2.140 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 13, 2026 License: Apache-2.0 Imports: 26 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ContextWithScopes

func ContextWithScopes(ctx context.Context, scopes []string) context.Context

ContextWithScopes carries the scopes granted to the access token on the current request. Set by Handler.ValidateToken from the token's metadata.

func ContextWithSessionID

func ContextWithSessionID(ctx context.Context, sessionID string) context.Context

ContextWithSessionID creates a context carrying a stable session identifier derived from the OAuth refresh token family. This allows consumers to associate per-session state with the current authenticated request.

func ContextWithUserInfo

func ContextWithUserInfo(ctx context.Context, userInfo *providers.UserInfo) context.Context

ContextWithUserInfo creates a context with the given user info. This is useful for testing code that depends on authenticated user context.

WARNING: This function should ONLY be used for testing. In production, user info should ONLY be set by the ValidateToken middleware after proper token validation. Using this function to bypass authentication in production code is a security vulnerability.

Note: if userInfo is nil, UserInfoFromContext will return (nil, true). Callers should check both the ok value and nil-ness of the returned userInfo.

func InterstitialAppName

func InterstitialAppName(ctx context.Context) string

InterstitialAppName extracts the application name from the request context. This is used by custom interstitial handlers to get the human-readable app name. Returns empty string if not found in context.

func InterstitialRedirectURL

func InterstitialRedirectURL(ctx context.Context) string

InterstitialRedirectURL extracts the OAuth redirect URL from the request context. This is used by custom interstitial handlers to get the redirect URL. Returns empty string if not found in context.

func ScopesFromContext

func ScopesFromContext(ctx context.Context) ([]string, bool)

ScopesFromContext returns the scopes granted to the access token on the current request. The bool is false when no scopes are present in the context.

func SessionIDFromContext

func SessionIDFromContext(ctx context.Context) (string, bool)

SessionIDFromContext retrieves the session identifier from the request context. Returns the session ID and true if present and non-empty, or ("", false) otherwise.

func UserInfoFromContext

func UserInfoFromContext(ctx context.Context) (*providers.UserInfo, bool)

UserInfoFromContext retrieves user info from the request context

Types

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler is a thin HTTP adapter for the OAuth Server. It handles HTTP requests and delegates to the Server for business logic.

func New

func New(server *server.Server, logger *slog.Logger) *Handler

NewHandler creates a new HTTP handler

func (*Handler) RegisterAuthorizationServerMetadataRoutes

func (h *Handler) RegisterAuthorizationServerMetadataRoutes(mux *http.ServeMux)

RegisterAuthorizationServerMetadataRoutes registers all Authorization Server Metadata discovery routes. This supports multi-tenant deployments with path-based issuers per MCP 2025-11-25.

For issuer URLs with path components (e.g., https://auth.example.com/tenant1), registers:

  1. Path insertion OAuth: /.well-known/oauth-authorization-server/tenant1
  2. Path insertion OIDC: /.well-known/openid-configuration/tenant1
  3. Path appending OIDC: /tenant1/.well-known/openid-configuration

For issuer URLs without path components (e.g., https://auth.example.com), registers:

  1. Standard OAuth: /.well-known/oauth-authorization-server
  2. Standard OIDC: /.well-known/openid-configuration

Example usage:

// Single-tenant: Configure issuer without path
config := &ServerConfig{
	Issuer: "https://auth.example.com",
}
// Registers: /.well-known/oauth-authorization-server
//            /.well-known/openid-configuration
handler.RegisterAuthorizationServerMetadataRoutes(mux)

// Multi-tenant: Configure issuer with path
config := &ServerConfig{
	Issuer: "https://auth.example.com/tenant1",
}
// Registers: /.well-known/oauth-authorization-server/tenant1
//            /.well-known/openid-configuration/tenant1
//            /tenant1/.well-known/openid-configuration
//            (plus standard endpoints for backward compatibility)
handler.RegisterAuthorizationServerMetadataRoutes(mux)

func (*Handler) RegisterOAuthRoutes

func (h *Handler) RegisterOAuthRoutes(mux *http.ServeMux, opts OAuthRoutesOptions)

RegisterOAuthRoutes registers the OAuth flow endpoints on mux and, when opts.IncludeMetadata is true (the default), also registers the Protected Resource Metadata and Authorization Server Metadata routes via the two existing Register*Routes helpers.

Routes registered (all under /oauth, paths fixed by the Config endpoint builders):

  • /oauth/authorize, /oauth/callback, /oauth/token, /oauth/revoke, /oauth/register — always registered.
  • /oauth/introspect — only when Config.EnableIntrospectionEndpoint is true. ServeTokenIntrospection does not self-gate on that flag, so registering it unconditionally would expose an endpoint the operator disabled in config.

A customizable prefix was considered and rejected — [Config.AuthorizationEndpoint], [Config.TokenEndpoint], and the other metadata builders hardcode the /oauth prefix when constructing the issuer-scoped URLs that appear in metadata. A custom prefix would make the routes register at one URL while metadata advertised a different one. Consumers needing a custom prefix must wire the individual Serve* methods by hand, at which point they also need to override metadata advertisement.

Replaces the five-line `mux.HandleFunc("/oauth/...", handler.Serve...)` block every consumer writes today:

handler.RegisterOAuthRoutes(mux, oauth.OAuthRoutesOptions{
    MCPPath:         "/mcp",
    IncludeMetadata: true,
})

func (*Handler) RegisterProtectedResourceMetadataRoutes

func (h *Handler) RegisterProtectedResourceMetadataRoutes(mux *http.ServeMux, mcpPath string)

RegisterProtectedResourceMetadataRoutes registers all Protected Resource Metadata discovery routes. It registers the root endpoint and optional sub-path endpoints based on configuration.

Route registration is done for:

  1. Root endpoint: /.well-known/oauth-protected-resource (always registered)
  2. Explicit mcpPath endpoint if provided (backward compatibility)
  3. All paths from ResourceMetadataByPath configuration (MCP 2025-11-25)

Security: This function validates all paths to prevent path traversal attacks and DoS through excessively long paths. Invalid paths are logged and skipped.

Example usage:

// Legacy single-path registration
handler.RegisterProtectedResourceMetadataRoutes(mux, "/mcp")

// With per-path configuration (new in MCP 2025-11-25)
// Configure in server.Config.ResourceMetadataByPath, then:
handler.RegisterProtectedResourceMetadataRoutes(mux, "")
// This registers routes for all configured paths automatically

func (*Handler) ServeAuthorization

func (h *Handler) ServeAuthorization(w http.ResponseWriter, r *http.Request)

ServeAuthorization handles OAuth authorization requests

func (*Handler) ServeAuthorizationServerMetadata

func (h *Handler) ServeAuthorizationServerMetadata(w http.ResponseWriter, r *http.Request)

ServeAuthorizationServerMetadata serves RFC 8414 Authorization Server Metadata

func (*Handler) ServeCallback

func (h *Handler) ServeCallback(w http.ResponseWriter, r *http.Request)

ServeCallback handles the OAuth provider callback

func (*Handler) ServeClientRegistration

func (h *Handler) ServeClientRegistration(w http.ResponseWriter, r *http.Request)

ServeClientRegistration handles dynamic client registration (RFC 7591)

func (*Handler) ServeJWKS

func (h *Handler) ServeJWKS(w http.ResponseWriter, r *http.Request)

ServeJWKS publishes the public half of the access-token signing key as a JSON Web Key Set per RFC 7517. Returns 404 when the server is configured for opaque-mode access tokens — the endpoint exists but advertising nothing is the honest response.

The handler reuses the discovery rate limiter so a hot loop against /.well-known/jwks.json cannot starve the rest of the server. Cache-Control is set to one hour: keys rotate manually (operator changes AccessTokenSigningKeyID and restarts), and verifiers caching for an hour is the conventional middle ground between churn and freshness.

func (*Handler) ServeOpenIDConfiguration

func (h *Handler) ServeOpenIDConfiguration(w http.ResponseWriter, r *http.Request)

ServeOpenIDConfiguration handles OpenID Connect Discovery 1.0 requests Per RFC 8414 Section 5, this endpoint returns the same metadata as the Authorization Server Metadata endpoint for compatibility with OpenID Connect clients

func (*Handler) ServePreflightRequest

func (h *Handler) ServePreflightRequest(w http.ResponseWriter, r *http.Request)

ServePreflightRequest handles CORS preflight (OPTIONS) requests. Required for non-simple requests (POST with JSON, custom headers, etc.).

func (*Handler) ServeProtectedResourceMetadata

func (h *Handler) ServeProtectedResourceMetadata(w http.ResponseWriter, r *http.Request)

ServeProtectedResourceMetadata serves RFC 9728 Protected Resource Metadata with support for path-specific metadata discovery per MCP 2025-11-25.

The handler extracts the resource path from the request URL and looks up path-specific configuration in ResourceMetadataByPath. If a match is found, path-specific metadata is returned; otherwise, default server-wide metadata is used.

Path matching uses longest-prefix matching. For example, given paths "/mcp/files" and "/mcp/files/admin", a request for "/mcp/files/admin/users" would match "/mcp/files/admin".

func (*Handler) ServeToken

func (h *Handler) ServeToken(w http.ResponseWriter, r *http.Request)

ServeToken handles the OAuth token endpoint

func (*Handler) ServeTokenIntrospection

func (h *Handler) ServeTokenIntrospection(w http.ResponseWriter, r *http.Request)

ServeTokenIntrospection handles the RFC 7662 token introspection endpoint This allows resource servers to validate access tokens Security: Requires client authentication to prevent token scanning attacks

func (*Handler) ServeTokenRevocation

func (h *Handler) ServeTokenRevocation(w http.ResponseWriter, r *http.Request)

ServeTokenRevocation handles the RFC 7009 token revocation endpoint

func (*Handler) ServeUserInfo

func (h *Handler) ServeUserInfo(w http.ResponseWriter, r *http.Request)

ServeUserInfo handles the OIDC UserInfo endpoint (OIDC Core 1.0 §5.3). Accepts GET and POST. The Handler.ValidateToken middleware authenticates the bearer access token and stashes the resolved providers.UserInfo and granted scopes in the request context; this handler renders the claims gated by those scopes.

The `openid` scope is REQUIRED to access the endpoint. The `sub` claim is always returned. `profile`, `email`, and `groups` scopes gate the corresponding claim groups.

func (*Handler) ValidateToken

func (h *Handler) ValidateToken(next http.Handler) http.Handler

ValidateToken is middleware that validates OAuth tokens

type OAuthRoutesOptions

type OAuthRoutesOptions struct {
	// MCPPath is forwarded to RegisterProtectedResourceMetadataRoutes for
	// backward compatibility with single-path consumers. Kept because a few
	// examples still pass it, but prefer configuring
	// [Config.ResourceMetadataByPath] instead — when that map is non-empty,
	// MCPPath is ignored (with a single warn log at registration time so the
	// conflict is visible).
	MCPPath string

	// IncludeMetadata controls whether the two discovery bundles
	// (Protected Resource Metadata per RFC 9728 and Authorization Server
	// Metadata per RFC 8414) are registered alongside the OAuth flow
	// endpoints. Default true — this is what every consumer today does by
	// hand.
	IncludeMetadata bool
}

OAuthRoutesOptions controls the bundle registered by Handler.RegisterOAuthRoutes.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL