Documentation
¶
Overview ¶
Package handlers provides HTTP handlers for the OAuth 2.0 authorization server endpoints.
This package implements the HTTP layer for the authorization server, including:
- OIDC Discovery endpoint (/.well-known/openid-configuration)
- JWKS endpoint (/.well-known/jwks.json)
- OAuth endpoints (authorize, token, callback, register) - to be implemented
The Handler struct coordinates all handlers and provides route registration methods for integrating with standard Go HTTP servers.
Index ¶
- Constants
- type Handler
- func (h *Handler) AuthorizeHandler(w http.ResponseWriter, req *http.Request)
- func (h *Handler) CallbackHandler(w http.ResponseWriter, req *http.Request)
- func (h *Handler) JWKSHandler(w http.ResponseWriter, _ *http.Request)
- func (h *Handler) OAuthDiscoveryHandler(w http.ResponseWriter, _ *http.Request)
- func (h *Handler) OAuthRoutes(r chi.Router)
- func (h *Handler) OIDCDiscoveryHandler(w http.ResponseWriter, _ *http.Request)
- func (h *Handler) RegisterClientHandler(w http.ResponseWriter, req *http.Request)
- func (h *Handler) Routes() http.Handler
- func (h *Handler) TokenHandler(w http.ResponseWriter, req *http.Request)
- func (h *Handler) WellKnownRoutes(r chi.Router)
- type NamedUpstream
- type UserResolver
Constants ¶
const ( // DefaultJWKSCacheMaxAge is the Cache-Control max-age for the JWKS endpoint (1 hour). // This balances caching efficiency with timely key rotation propagation. DefaultJWKSCacheMaxAge = 3600 // DefaultDiscoveryCacheMaxAge is the Cache-Control max-age for the discovery endpoint (1 hour). // Aligned with Google's OIDC discovery cache policy. DefaultDiscoveryCacheMaxAge = 3600 )
Cache-Control max-age values for discovery endpoints. These are not exposed to users but extracted as constants for documentation and maintainability.
const MaxDCRBodySize = 64 * 1024
MaxDCRBodySize is the maximum allowed size for DCR request bodies (64KB). This prevents DoS attacks via extremely large payloads while being generous enough for legitimate requests with multiple redirect URIs.
It is exported to serve as the single source of truth for the auth-server body-size cap: the embedded auth server (pkg/authserver/runner) derives its own request-body limit from this constant so the two cannot drift.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler provides HTTP handlers for the OAuth authorization server endpoints.
func NewHandler ¶
func NewHandler( provider fosite.OAuth2Provider, config *server.AuthorizationServerConfig, stor storage.Storage, upstreams []NamedUpstream, ) (*Handler, error)
NewHandler creates a new Handler with the given dependencies. upstreams defines the ordered sequence of upstream providers consulted during multi-upstream authorization flows (e.g., sequential token acquisition).
Returns an error if config is nil, if config's embedded *fosite.Config is nil, if upstreams is empty, or if any entry has an empty name or nil provider. Catching misconfiguration here is far easier to diagnose than a nil-deref panic deep inside an HTTP handler at request time.
func (*Handler) AuthorizeHandler ¶ added in v0.8.1
func (h *Handler) AuthorizeHandler(w http.ResponseWriter, req *http.Request)
AuthorizeHandler handles GET /oauth/authorize requests. It validates the client's authorization request and redirects to the upstream IDP.
func (*Handler) CallbackHandler ¶ added in v0.8.1
func (h *Handler) CallbackHandler(w http.ResponseWriter, req *http.Request)
CallbackHandler handles GET /oauth/callback requests. It exchanges the upstream authorization code and issues our own authorization code.
func (*Handler) JWKSHandler ¶
func (h *Handler) JWKSHandler(w http.ResponseWriter, _ *http.Request)
JWKSHandler handles GET /.well-known/jwks.json requests. It returns the public keys used for verifying JWTs.
func (*Handler) OAuthDiscoveryHandler ¶
func (h *Handler) OAuthDiscoveryHandler(w http.ResponseWriter, _ *http.Request)
OAuthDiscoveryHandler handles GET /.well-known/oauth-authorization-server requests. It returns the OAuth 2.0 Authorization Server Metadata per RFC 8414. This endpoint is useful for non-OIDC OAuth clients.
func (*Handler) OAuthRoutes ¶
OAuthRoutes registers OAuth endpoints (authorize, callback, token, register) on the provided router.
func (*Handler) OIDCDiscoveryHandler ¶
func (h *Handler) OIDCDiscoveryHandler(w http.ResponseWriter, _ *http.Request)
OIDCDiscoveryHandler handles GET /.well-known/openid-configuration requests. It returns the OIDC discovery document describing the authorization server capabilities. This extends the OAuth 2.0 AS Metadata (RFC 8414) with OIDC-specific fields.
func (*Handler) RegisterClientHandler ¶ added in v0.8.1
func (h *Handler) RegisterClientHandler(w http.ResponseWriter, req *http.Request)
RegisterClientHandler handles POST /oauth/register requests. It implements RFC 7591 Dynamic Client Registration for public clients with loopback redirect URIs only.
func (*Handler) TokenHandler ¶ added in v0.8.1
func (h *Handler) TokenHandler(w http.ResponseWriter, req *http.Request)
TokenHandler handles POST /oauth/token requests. It processes token requests using fosite's access request/response flow.
func (*Handler) WellKnownRoutes ¶
WellKnownRoutes registers well-known endpoints (JWKS, OAuth/OIDC discovery) on the provided router. Both discovery endpoints are registered per the MCP specification requirement to provide at least one discovery mechanism, with both supported for maximum interoperability: - /.well-known/oauth-authorization-server (RFC 8414) for OAuth-only clients - /.well-known/openid-configuration (OIDC Discovery 1.0) for OIDC clients
The wildcard variants (/.well-known/oauth-authorization-server/*) handle RFC 8414 Section 3.1 path-based issuers, where clients insert /.well-known/ before the issuer's path component (e.g., /.well-known/oauth-authorization-server/inject-test for issuer https://example.com/inject-test).
type NamedUpstream ¶ added in v0.12.5
type NamedUpstream struct {
Name string
Provider upstream.OAuth2Provider
}
NamedUpstream pairs a logical provider name with its OAuth2Provider implementation. The name is used as the storage key and must be unique within the upstream slice.
type UserResolver ¶ added in v0.8.1
type UserResolver struct {
// contains filtered or unexported fields
}
UserResolver handles finding or creating users based on provider identity. It manages the mapping between upstream provider subjects and internal user IDs.
func NewUserResolver ¶ added in v0.8.1
func NewUserResolver(stor storage.UserStorage) *UserResolver
NewUserResolver creates a new UserResolver with the given storage.
func (*UserResolver) ResolveUser ¶ added in v0.8.1
func (r *UserResolver) ResolveUser( ctx context.Context, providerID string, providerSubject string, ) (*storage.User, error)
ResolveUser finds an existing user or creates a new one for the provider identity. Returns the user whose ID will be the "sub" claim in our JWTs.
The resolution process: 1. Look up existing identity by (providerID, providerSubject) 2. If found, return the linked user 3. If not found, create a new user and link the identity
func (*UserResolver) UpdateLastAuthenticated ¶ added in v0.8.1
func (r *UserResolver) UpdateLastAuthenticated( ctx context.Context, providerID string, providerSubject string, )
UpdateLastAuthenticated updates the last authentication timestamp for a provider identity. This supports OIDC max_age parameter enforcement by tracking when users last authenticated. Errors are logged but not fatal - callers should continue with authorization.