Documentation
¶
Overview ¶
Package oauth provides OAuth 2.1 server capabilities.
Index ¶
- Variables
- func BuildAuthorizationURL(baseURL, clientID, redirectURI, scope, state string) string
- func GenerateCodeChallenge(verifier string, method PKCEMethod) (string, error)
- func ValidateCodeChallenge(challenge string) error
- func ValidateCodeVerifier(verifier string) error
- func VerifyCodeChallenge(verifier, challenge string, method PKCEMethod) (bool, error)
- type AuthorizationCode
- type AuthorizationRequest
- type AuthorizationState
- type Client
- type DCRConfig
- type DCRRequest
- type DCRResponse
- type DCRService
- type ErrorResponse
- type MemoryStateStore
- type MemoryStorage
- func (m *MemoryStorage) CleanupExpiredCodes(_ context.Context) error
- func (m *MemoryStorage) CleanupExpiredTokens(_ context.Context) error
- func (m *MemoryStorage) CreateClient(_ context.Context, client *Client) error
- func (m *MemoryStorage) DeleteAuthorizationCode(_ context.Context, code string) error
- func (m *MemoryStorage) DeleteClient(_ context.Context, clientID string) error
- func (m *MemoryStorage) DeleteRefreshToken(_ context.Context, token string) error
- func (m *MemoryStorage) DeleteRefreshTokensForClient(_ context.Context, clientID string) error
- func (m *MemoryStorage) GetAuthorizationCode(_ context.Context, code string) (*AuthorizationCode, error)
- func (m *MemoryStorage) GetClient(_ context.Context, clientID string) (*Client, error)
- func (m *MemoryStorage) GetRefreshToken(_ context.Context, token string) (*RefreshToken, error)
- func (m *MemoryStorage) ListClients(_ context.Context) ([]*Client, error)
- func (m *MemoryStorage) SaveAuthorizationCode(_ context.Context, code *AuthorizationCode) error
- func (m *MemoryStorage) SaveRefreshToken(_ context.Context, token *RefreshToken) error
- func (m *MemoryStorage) UpdateClient(_ context.Context, client *Client) error
- type PKCEMethod
- type RefreshToken
- type Server
- func (s *Server) Authorize(ctx context.Context, req AuthorizationRequest, userID string, ...) (string, error)
- func (s *Server) Issuer() string
- func (s *Server) RegisterClient(ctx context.Context, req DCRRequest) (*DCRResponse, error)
- func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (s *Server) SigningKey() []byte
- func (s *Server) StartCleanupRoutine(ctx context.Context, interval time.Duration)
- func (s *Server) Token(ctx context.Context, req TokenRequest) (*TokenResponse, error)
- type ServerConfig
- type StateStore
- type Storage
- type TokenRequest
- type TokenResponse
- type UpstreamConfig
Constants ¶
This section is empty.
Variables ¶
var (
ErrStateNotFound = errors.New("authorization state not found")
)
Errors returned by the OAuth server.
Functions ¶
func BuildAuthorizationURL ¶
BuildAuthorizationURL builds an authorization URL. Uses paths without /oauth prefix for Claude Desktop compatibility.
func GenerateCodeChallenge ¶
func GenerateCodeChallenge(verifier string, method PKCEMethod) (string, error)
GenerateCodeChallenge generates a code challenge from a verifier.
func ValidateCodeChallenge ¶
ValidateCodeChallenge validates a code challenge.
func ValidateCodeVerifier ¶
ValidateCodeVerifier validates a code verifier. Per RFC 7636, it must be 43-128 characters of [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~".
func VerifyCodeChallenge ¶
func VerifyCodeChallenge(verifier, challenge string, method PKCEMethod) (bool, error)
VerifyCodeChallenge verifies a code verifier against a challenge.
Types ¶
type AuthorizationCode ¶
type AuthorizationCode struct {
ID string `json:"id"`
Code string `json:"code"`
ClientID string `json:"client_id"`
UserID string `json:"user_id"`
UserClaims map[string]any `json:"user_claims"`
CodeChallenge string `json:"code_challenge"`
RedirectURI string `json:"redirect_uri"`
Scope string `json:"scope"`
ExpiresAt time.Time `json:"expires_at"`
Used bool `json:"used"`
CreatedAt time.Time `json:"created_at"`
}
AuthorizationCode represents an OAuth authorization code.
func (*AuthorizationCode) IsExpired ¶
func (c *AuthorizationCode) IsExpired() bool
IsExpired checks if the authorization code has expired.
type AuthorizationRequest ¶
type AuthorizationRequest struct {
ResponseType string
ClientID string
RedirectURI string
Scope string
State string
CodeChallenge string
CodeChallengeMethod string
}
AuthorizationRequest represents an authorization request.
type AuthorizationState ¶ added in v0.3.0
type AuthorizationState struct {
// ClientID is the OAuth client's client_id (e.g., Claude Desktop).
ClientID string
// RedirectURI is where to send the client after authentication.
RedirectURI string
// State is the client's original state parameter.
State string
// CodeChallenge is the PKCE challenge from the client.
CodeChallenge string
// CodeChallengeMethod is the PKCE method (S256 or plain).
CodeChallengeMethod string
// Scope is the requested scope.
Scope string
// UpstreamState is the state for the upstream IdP (e.g., Keycloak).
UpstreamState string
// CreatedAt is when this state was created.
CreatedAt time.Time
}
AuthorizationState holds state for linking upstream IdP callbacks to original client authorization requests.
type Client ¶
type Client struct {
ID string `json:"id"`
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"` // bcrypt hashed
Name string `json:"name"`
RedirectURIs []string `json:"redirect_uris"`
GrantTypes []string `json:"grant_types"`
RequirePKCE bool `json:"require_pkce"`
CreatedAt time.Time `json:"created_at"`
Active bool `json:"active"`
}
Client represents an OAuth 2.1 client.
func (*Client) SupportsGrantType ¶
SupportsGrantType checks if the client supports a grant type.
func (*Client) ValidRedirectURI ¶
ValidRedirectURI checks if a redirect URI is valid for this client.
type DCRConfig ¶
type DCRConfig struct {
// Enabled enables DCR.
Enabled bool
// AllowedRedirectPatterns are regex patterns for allowed redirect URIs.
AllowedRedirectPatterns []string
// DefaultGrantTypes are the default grant types for new clients.
DefaultGrantTypes []string
// RequirePKCE requires PKCE for all clients.
RequirePKCE bool
}
DCRConfig configures Dynamic Client Registration.
type DCRRequest ¶
type DCRRequest struct {
ClientName string `json:"client_name"`
RedirectURIs []string `json:"redirect_uris"`
GrantTypes []string `json:"grant_types,omitempty"`
TokenEndpointAuthMethod string `json:"token_endpoint_auth_method,omitempty"`
}
DCRRequest is a Dynamic Client Registration request.
type DCRResponse ¶
type DCRResponse struct {
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret,omitempty"`
ClientName string `json:"client_name"`
RedirectURIs []string `json:"redirect_uris"`
GrantTypes []string `json:"grant_types"`
ClientSecretExpiresAt int `json:"client_secret_expires_at"` // 0 means never
}
DCRResponse is a Dynamic Client Registration response.
type DCRService ¶
type DCRService struct {
// contains filtered or unexported fields
}
DCRService handles Dynamic Client Registration.
func NewDCRService ¶
func NewDCRService(storage Storage, config DCRConfig) (*DCRService, error)
NewDCRService creates a new DCR service.
func (*DCRService) Register ¶
func (s *DCRService) Register(ctx context.Context, req DCRRequest) (*DCRResponse, error)
Register registers a new OAuth client.
type ErrorResponse ¶
type ErrorResponse struct {
Error string `json:"error"`
ErrorDescription string `json:"error_description,omitempty"`
}
ErrorResponse represents an OAuth error response.
type MemoryStateStore ¶ added in v0.3.0
type MemoryStateStore struct {
// contains filtered or unexported fields
}
MemoryStateStore is an in-memory implementation of StateStore.
func NewMemoryStateStore ¶ added in v0.3.0
func NewMemoryStateStore() *MemoryStateStore
NewMemoryStateStore creates a new in-memory state store.
func (*MemoryStateStore) Cleanup ¶ added in v0.3.0
func (s *MemoryStateStore) Cleanup(maxAge time.Duration) error
Cleanup removes states older than maxAge.
func (*MemoryStateStore) Delete ¶ added in v0.3.0
func (s *MemoryStateStore) Delete(key string) error
Delete removes an authorization state.
func (*MemoryStateStore) Get ¶ added in v0.3.0
func (s *MemoryStateStore) Get(key string) (*AuthorizationState, error)
Get retrieves an authorization state.
func (*MemoryStateStore) Save ¶ added in v0.3.0
func (s *MemoryStateStore) Save(key string, state *AuthorizationState) error
Save stores an authorization state.
type MemoryStorage ¶ added in v0.3.0
type MemoryStorage struct {
// contains filtered or unexported fields
}
MemoryStorage is an in-memory implementation of Storage. It is thread-safe and suitable for development/testing. For production, use PostgresStorage.
func NewMemoryStorage ¶ added in v0.3.0
func NewMemoryStorage() *MemoryStorage
NewMemoryStorage creates a new in-memory storage.
func (*MemoryStorage) CleanupExpiredCodes ¶ added in v0.3.0
func (m *MemoryStorage) CleanupExpiredCodes(_ context.Context) error
CleanupExpiredCodes removes expired authorization codes.
func (*MemoryStorage) CleanupExpiredTokens ¶ added in v0.3.0
func (m *MemoryStorage) CleanupExpiredTokens(_ context.Context) error
CleanupExpiredTokens removes expired refresh tokens.
func (*MemoryStorage) CreateClient ¶ added in v0.3.0
func (m *MemoryStorage) CreateClient(_ context.Context, client *Client) error
CreateClient stores a new client.
func (*MemoryStorage) DeleteAuthorizationCode ¶ added in v0.3.0
func (m *MemoryStorage) DeleteAuthorizationCode(_ context.Context, code string) error
DeleteAuthorizationCode deletes an authorization code.
func (*MemoryStorage) DeleteClient ¶ added in v0.3.0
func (m *MemoryStorage) DeleteClient(_ context.Context, clientID string) error
DeleteClient deletes a client.
func (*MemoryStorage) DeleteRefreshToken ¶ added in v0.3.0
func (m *MemoryStorage) DeleteRefreshToken(_ context.Context, token string) error
DeleteRefreshToken deletes a refresh token.
func (*MemoryStorage) DeleteRefreshTokensForClient ¶ added in v0.3.0
func (m *MemoryStorage) DeleteRefreshTokensForClient(_ context.Context, clientID string) error
DeleteRefreshTokensForClient deletes all refresh tokens for a client.
func (*MemoryStorage) GetAuthorizationCode ¶ added in v0.3.0
func (m *MemoryStorage) GetAuthorizationCode(_ context.Context, code string) (*AuthorizationCode, error)
GetAuthorizationCode retrieves an authorization code.
func (*MemoryStorage) GetRefreshToken ¶ added in v0.3.0
func (m *MemoryStorage) GetRefreshToken(_ context.Context, token string) (*RefreshToken, error)
GetRefreshToken retrieves a refresh token.
func (*MemoryStorage) ListClients ¶ added in v0.3.0
func (m *MemoryStorage) ListClients(_ context.Context) ([]*Client, error)
ListClients returns all clients.
func (*MemoryStorage) SaveAuthorizationCode ¶ added in v0.3.0
func (m *MemoryStorage) SaveAuthorizationCode(_ context.Context, code *AuthorizationCode) error
SaveAuthorizationCode stores an authorization code.
func (*MemoryStorage) SaveRefreshToken ¶ added in v0.3.0
func (m *MemoryStorage) SaveRefreshToken(_ context.Context, token *RefreshToken) error
SaveRefreshToken stores a refresh token.
func (*MemoryStorage) UpdateClient ¶ added in v0.3.0
func (m *MemoryStorage) UpdateClient(_ context.Context, client *Client) error
UpdateClient updates an existing client.
type PKCEMethod ¶
type PKCEMethod string
PKCEMethod defines the code challenge method.
const ( // PKCEMethodPlain uses plain text (not recommended). PKCEMethodPlain PKCEMethod = "plain" // PKCEMethodS256 uses SHA-256 hashing (recommended). PKCEMethodS256 PKCEMethod = "S256" )
func DefaultPKCEMethod ¶
func DefaultPKCEMethod() PKCEMethod
DefaultPKCEMethod returns the default (and recommended) PKCE method.
type RefreshToken ¶
type RefreshToken struct {
ID string `json:"id"`
Token string `json:"token"`
ClientID string `json:"client_id"`
UserID string `json:"user_id"`
UserClaims map[string]any `json:"user_claims"`
Scope string `json:"scope"`
ExpiresAt time.Time `json:"expires_at"`
CreatedAt time.Time `json:"created_at"`
}
RefreshToken represents an OAuth refresh token.
func (*RefreshToken) IsExpired ¶
func (t *RefreshToken) IsExpired() bool
IsExpired checks if the refresh token has expired.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is an OAuth 2.1 authorization server.
func NewServer ¶
func NewServer(config ServerConfig, storage Storage) (*Server, error)
NewServer creates a new OAuth server.
func (*Server) Authorize ¶
func (s *Server) Authorize(ctx context.Context, req AuthorizationRequest, userID string, userClaims map[string]any) (string, error)
Authorize handles the authorization endpoint.
func (*Server) RegisterClient ¶
func (s *Server) RegisterClient(ctx context.Context, req DCRRequest) (*DCRResponse, error)
RegisterClient handles Dynamic Client Registration.
func (*Server) ServeHTTP ¶
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP implements http.Handler for the OAuth server. Handles both standard paths (with /oauth prefix) and Claude Desktop compatible paths (without prefix).
func (*Server) SigningKey ¶ added in v0.4.0
SigningKey returns the OAuth server's signing key. This is needed by the OAuth JWT authenticator to validate tokens.
func (*Server) StartCleanupRoutine ¶
StartCleanupRoutine starts a background routine to clean up expired codes and tokens.
func (*Server) Token ¶
func (s *Server) Token(ctx context.Context, req TokenRequest) (*TokenResponse, error)
Token handles the token endpoint.
type ServerConfig ¶
type ServerConfig struct {
// Issuer is the OAuth issuer URL.
Issuer string
// AccessTokenTTL is the access token lifetime.
AccessTokenTTL time.Duration
// RefreshTokenTTL is the refresh token lifetime.
RefreshTokenTTL time.Duration
// AuthCodeTTL is the authorization code lifetime.
AuthCodeTTL time.Duration
// SigningKey is the HMAC key used to sign JWT access tokens.
// If not provided, tokens will be opaque (not recommended for production).
// Generate with: openssl rand -base64 32
SigningKey []byte
// DCR configures Dynamic Client Registration.
DCR DCRConfig
// Upstream configures the upstream identity provider (e.g., Keycloak).
Upstream *UpstreamConfig
}
ServerConfig configures the OAuth server.
type StateStore ¶ added in v0.3.0
type StateStore interface {
// Save stores an authorization state.
Save(key string, state *AuthorizationState) error
// Get retrieves an authorization state.
Get(key string) (*AuthorizationState, error)
// Delete removes an authorization state.
Delete(key string) error
// Cleanup removes expired states.
Cleanup(maxAge time.Duration) error
}
StateStore manages authorization states for the OAuth flow.
type Storage ¶
type Storage interface {
// Client management
CreateClient(ctx context.Context, client *Client) error
GetClient(ctx context.Context, clientID string) (*Client, error)
UpdateClient(ctx context.Context, client *Client) error
DeleteClient(ctx context.Context, clientID string) error
ListClients(ctx context.Context) ([]*Client, error)
// Authorization code management
SaveAuthorizationCode(ctx context.Context, code *AuthorizationCode) error
GetAuthorizationCode(ctx context.Context, code string) (*AuthorizationCode, error)
DeleteAuthorizationCode(ctx context.Context, code string) error
CleanupExpiredCodes(ctx context.Context) error
// Token management
SaveRefreshToken(ctx context.Context, token *RefreshToken) error
GetRefreshToken(ctx context.Context, token string) (*RefreshToken, error)
DeleteRefreshToken(ctx context.Context, token string) error
DeleteRefreshTokensForClient(ctx context.Context, clientID string) error
CleanupExpiredTokens(ctx context.Context) error
}
Storage defines the interface for OAuth data persistence.
type TokenRequest ¶
type TokenRequest struct {
GrantType string
Code string
RedirectURI string
ClientID string
ClientSecret string
CodeVerifier string
RefreshToken string
Scope string
}
TokenRequest represents a token request.
type TokenResponse ¶
type TokenResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
RefreshToken string `json:"refresh_token,omitempty"`
Scope string `json:"scope,omitempty"`
}
TokenResponse represents a token response.
type UpstreamConfig ¶ added in v0.3.0
type UpstreamConfig struct {
// Issuer is the upstream IdP issuer URL (e.g., Keycloak realm URL).
Issuer string
// ClientID is the MCP server's client ID in the upstream IdP.
ClientID string
// ClientSecret is the MCP server's client secret.
ClientSecret string
// RedirectURI is the callback URL for the upstream IdP.
RedirectURI string
}
UpstreamConfig configures the upstream identity provider.