registration

package
v0.7.1 Latest Latest
Warning

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

Go to latest
Published: Jan 15, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package registration provides OAuth client types and utilities, including RFC 8252 compliant loopback redirect URI support for native OAuth clients.

Package registration provides OAuth 2.0 Dynamic Client Registration (DCR) functionality per RFC 7591, including request validation and secure redirect URI handling for public native clients.

Index

Constants

View Source
const (
	// DCRErrorInvalidRedirectURI indicates that the value of one or more
	// redirect_uris is invalid.
	DCRErrorInvalidRedirectURI = "invalid_redirect_uri"

	// DCRErrorInvalidClientMetadata indicates that the value of one of the
	// client metadata fields is invalid and the server has rejected this request.
	DCRErrorInvalidClientMetadata = "invalid_client_metadata"
)

DCR error codes per RFC 7591 Section 3.2.2

View Source
const (
	// MaxRedirectURILength is the maximum allowed length for a single redirect URI.
	MaxRedirectURILength = 2048

	// MaxRedirectURICount is the maximum number of redirect URIs allowed per client.
	MaxRedirectURICount = 10
)

Validation limits to prevent DoS attacks via excessively large requests.

Variables

View Source
var DefaultGrantTypes = []string{"authorization_code", "refresh_token"}

DefaultGrantTypes are the default grant types for registered clients.

View Source
var DefaultResponseTypes = []string{"code"}

DefaultResponseTypes are the default response types for registered clients.

View Source
var DefaultScopes = []string{"openid", "profile", "email"}

DefaultScopes are the default OIDC scopes for registered clients.

Functions

func New

func New(cfg Config) (fosite.Client, error)

New creates a fosite.Client from the given configuration. Public clients are wrapped in LoopbackClient to support RFC 8252 Section 7.3 compliant loopback redirect URI matching for native OAuth clients. Confidential clients with secrets have their Secret field bcrypt-hashed as required by fosite for credential validation.

func ValidateDCRRequest

func ValidateDCRRequest(req *DCRRequest) (*DCRRequest, *DCRError)

ValidateDCRRequest validates a DCR request according to RFC 7591 and the server's security policy (loopback-only public clients). Returns the validated request with defaults applied, or an error.

Types

type Config

type Config struct {
	// ID is the unique client identifier.
	ID string

	// Secret is the client secret for confidential clients.
	// Empty for public clients.
	Secret string

	// RedirectURIs is the list of allowed redirect URIs.
	RedirectURIs []string

	// Public indicates whether this is a public client (no secret).
	Public bool

	// GrantTypes overrides the default grant types.
	// If nil or empty, DefaultGrantTypes is used.
	GrantTypes []string

	// ResponseTypes overrides the default response types.
	// If nil or empty, DefaultResponseTypes is used.
	ResponseTypes []string

	// Scopes overrides the default scopes.
	// If nil or empty, DefaultScopes is used.
	Scopes []string
}

Config holds configuration for creating a new OAuth client.

type DCRError

type DCRError struct {
	// Error is a single ASCII error code from the defined set.
	Error string `json:"error"`

	// ErrorDescription is a human-readable text providing additional information.
	ErrorDescription string `json:"error_description,omitempty"`
}

DCRError represents an OAuth 2.0 Dynamic Client Registration error response per RFC 7591 Section 3.2.2.

func ValidateRedirectURI

func ValidateRedirectURI(uri string) *DCRError

ValidateRedirectURI validates a redirect URI per RFC 8252: - HTTPS is allowed for any address (web-based redirects) - HTTP is only allowed for loopback addresses (127.0.0.1, [::1], localhost)

type DCRRequest

type DCRRequest struct {
	// RedirectURIs is an array of redirection URIs for the client.
	// Required for public clients.
	RedirectURIs []string `json:"redirect_uris"`

	// ClientName is a human-readable name for the client.
	ClientName string `json:"client_name,omitempty"`

	// TokenEndpointAuthMethod is the requested authentication method for the token endpoint.
	// For public clients, this must be "none".
	TokenEndpointAuthMethod string `json:"token_endpoint_auth_method,omitempty"`

	// GrantTypes is an array of OAuth 2.0 grant types the client may use.
	// Defaults to ["authorization_code"] if not specified.
	GrantTypes []string `json:"grant_types,omitempty"`

	// ResponseTypes is an array of OAuth 2.0 response types the client may use.
	// Defaults to ["code"] if not specified.
	ResponseTypes []string `json:"response_types,omitempty"`
}

DCRRequest represents an OAuth 2.0 Dynamic Client Registration request per RFC 7591 Section 2.

type DCRResponse

type DCRResponse struct {
	// ClientID is the unique identifier for the client.
	ClientID string `json:"client_id"`

	// ClientIDIssuedAt is the time at which the client identifier was issued,
	// as a Unix timestamp.
	ClientIDIssuedAt int64 `json:"client_id_issued_at,omitempty"`

	// RedirectURIs is an array of redirection URIs for the client.
	RedirectURIs []string `json:"redirect_uris"`

	// ClientName is a human-readable name for the client.
	ClientName string `json:"client_name,omitempty"`

	// TokenEndpointAuthMethod is the authentication method for the token endpoint.
	TokenEndpointAuthMethod string `json:"token_endpoint_auth_method"`

	// GrantTypes is an array of OAuth 2.0 grant types the client may use.
	GrantTypes []string `json:"grant_types"`

	// ResponseTypes is an array of OAuth 2.0 response types the client may use.
	ResponseTypes []string `json:"response_types"`
}

DCRResponse represents a successful OAuth 2.0 Dynamic Client Registration response per RFC 7591 Section 3.2.1.

type LoopbackClient

type LoopbackClient struct {
	*fosite.DefaultClient
}

LoopbackClient is a fosite.Client implementation that supports RFC 8252 Section 7.3 compliant loopback redirect URI matching for native OAuth clients.

RFC 8252 Section 7.3 specifies that:

  • Loopback redirect URIs use "http" (not "https")
  • The host must be "127.0.0.1", "[::1]", or "localhost"
  • The authorization server MUST allow any port
  • The path and query components must match exactly

This client extends fosite's built-in loopback support to also handle "localhost" as a loopback address. Fosite's isMatchingAsLoopback uses isLoopbackAddress() which only supports IP addresses (net.ParseIP().IsLoopback()), not the "localhost" hostname. This is needed for DCR with clients like VS Code, Claude Code, and other native apps that register redirect URIs like "http://localhost/callback" and then request authorization with dynamic ports like "http://localhost:57403/callback".

func NewLoopbackClient

func NewLoopbackClient(client *fosite.DefaultClient) *LoopbackClient

NewLoopbackClient creates a new LoopbackClient wrapping the provided DefaultClient.

func (*LoopbackClient) GetMatchingRedirectURI

func (c *LoopbackClient) GetMatchingRedirectURI(requestedURI string) string

GetMatchingRedirectURI returns the matching redirect URI if found, or an empty string. For loopback URIs, returns the requested URI (with its port) if it matches a registered loopback pattern.

func (*LoopbackClient) MatchRedirectURI

func (c *LoopbackClient) MatchRedirectURI(requestedURI string) bool

MatchRedirectURI checks if the given redirect URI matches one of the client's registered redirect URIs, with RFC 8252 Section 7.3 loopback support.

For loopback URIs (127.0.0.1, [::1], or localhost), the port is allowed to vary while the scheme, host, path, and query must match exactly.

Jump to

Keyboard shortcuts

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