Documentation
¶
Overview ¶
Package oauth2 provides a pluggable OAuth2/OIDC provider abstraction for social login. Each provider implements the Provider interface to handle authorization URL generation, token exchange, and user info retrieval. Implementations include GoogleProvider (with PKCE S256), GitHubProvider, and FacebookProvider.
Index ¶
- type FacebookProvider
- func (f *FacebookProvider) AuthURL(state, nonce, codeChallenge string) string
- func (f *FacebookProvider) Exchange(ctx context.Context, code, codeVerifier string) (*TokenResponse, error)
- func (f *FacebookProvider) Name() string
- func (f *FacebookProvider) UserInfo(ctx context.Context, accessToken string) (*UserInfo, error)
- type GitHubProvider
- func (g *GitHubProvider) AuthURL(state, nonce, codeChallenge string) string
- func (g *GitHubProvider) Exchange(ctx context.Context, code, codeVerifier string) (*TokenResponse, error)
- func (g *GitHubProvider) Name() string
- func (g *GitHubProvider) UserInfo(ctx context.Context, accessToken string) (*UserInfo, error)
- type GoogleProvider
- func (g *GoogleProvider) AuthURL(state, nonce, codeChallenge string) string
- func (g *GoogleProvider) Exchange(ctx context.Context, code, codeVerifier string) (*TokenResponse, error)
- func (g *GoogleProvider) Name() string
- func (g *GoogleProvider) UserInfo(ctx context.Context, accessToken string) (*UserInfo, error)
- type OIDCProvider
- func (p *OIDCProvider) AuthURL(state, nonce, codeChallenge string) string
- func (p *OIDCProvider) Exchange(ctx context.Context, code, codeVerifier string) (*TokenResponse, error)
- func (p *OIDCProvider) Name() string
- func (p *OIDCProvider) SetGuard(g *outbound.Policy)
- func (p *OIDCProvider) UserInfo(ctx context.Context, accessToken string) (*UserInfo, error)
- func (p *OIDCProvider) VerifyIDToken(ctx context.Context, idToken, expectedNonce string) (*UserInfo, error)
- type Provider
- type TokenResponse
- type UserInfo
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type FacebookProvider ¶
type FacebookProvider struct {
// contains filtered or unexported fields
}
FacebookProvider implements the Provider interface for Facebook OAuth2. Uses PKCE S256 code challenge for authorization code exchange security.
func NewFacebookProvider ¶
func NewFacebookProvider(clientID, clientSecret, redirectURI string) *FacebookProvider
NewFacebookProvider creates a Facebook OAuth2 provider with the given credentials and redirect URI.
func (*FacebookProvider) AuthURL ¶
func (f *FacebookProvider) AuthURL(state, nonce, codeChallenge string) string
AuthURL returns the Facebook OAuth2 authorization URL with PKCE S256 code challenge. The nonce parameter is ignored as Facebook does not support OIDC.
func (*FacebookProvider) Exchange ¶
func (f *FacebookProvider) Exchange(ctx context.Context, code, codeVerifier string) (*TokenResponse, error)
Exchange trades an authorization code for an access token via Facebook's token endpoint, using the PKCE code verifier for validation.
type GitHubProvider ¶
type GitHubProvider struct {
// contains filtered or unexported fields
}
GitHubProvider implements the Provider interface for GitHub OAuth2. Uses PKCE S256 code challenge for authorization code exchange security.
func NewGitHubProvider ¶
func NewGitHubProvider(clientID, clientSecret, redirectURI string) *GitHubProvider
NewGitHubProvider creates a GitHub OAuth2 provider with the given credentials and redirect URI.
func (*GitHubProvider) AuthURL ¶
func (g *GitHubProvider) AuthURL(state, nonce, codeChallenge string) string
AuthURL returns the GitHub OAuth2 authorization URL with PKCE S256 code challenge. The nonce parameter is ignored as GitHub does not support OIDC.
func (*GitHubProvider) Exchange ¶
func (g *GitHubProvider) Exchange(ctx context.Context, code, codeVerifier string) (*TokenResponse, error)
Exchange trades an authorization code for an access token via GitHub's token endpoint, using the PKCE code verifier for validation.
type GoogleProvider ¶
type GoogleProvider struct {
// contains filtered or unexported fields
}
GoogleProvider implements the Provider interface for Google OAuth2/OIDC. It uses PKCE S256 code challenge and requests offline access for refresh tokens.
func NewGoogleProvider ¶
func NewGoogleProvider(clientID, clientSecret, redirectURI string) *GoogleProvider
NewGoogleProvider creates a Google OAuth2/OIDC provider with the given credentials and redirect URI.
func (*GoogleProvider) AuthURL ¶
func (g *GoogleProvider) AuthURL(state, nonce, codeChallenge string) string
AuthURL returns the Google OAuth2 authorization URL with PKCE S256 code challenge, nonce for OIDC, and offline access type for refresh tokens.
func (*GoogleProvider) Exchange ¶
func (g *GoogleProvider) Exchange(ctx context.Context, code, codeVerifier string) (*TokenResponse, error)
Exchange trades an authorization code for tokens via Google's token endpoint, using the PKCE code verifier for validation.
type OIDCProvider ¶ added in v0.8.0
type OIDCProvider struct {
// contains filtered or unexported fields
}
OIDCProvider implements Provider for any standards-compliant OpenID Connect issuer (Okta, Auth0, Authentik, Keycloak, Entra, Google-OIDC, …). Endpoints are resolved via OIDC discovery ({issuer}/.well-known/openid-configuration), cached after the first fetch. Uses PKCE S256 + a nonce on the authorize request.
func NewOIDCProvider ¶ added in v0.8.0
func NewOIDCProvider(name, issuer, clientID, clientSecret, redirectURI, scopes string) *OIDCProvider
NewOIDCProvider builds a generic OIDC provider. name is the provider key used in routes/state (e.g. "okta"); scopes is optional (space-delimited).
func (*OIDCProvider) AuthURL ¶ added in v0.8.0
func (p *OIDCProvider) AuthURL(state, nonce, codeChallenge string) string
AuthURL builds the authorize URL. Returns "" if discovery fails (the handler's redirect guard rejects an empty/invalid URL).
func (*OIDCProvider) Exchange ¶ added in v0.8.0
func (p *OIDCProvider) Exchange(ctx context.Context, code, codeVerifier string) (*TokenResponse, error)
Exchange swaps an authorization code for tokens at the discovered token endpoint.
func (*OIDCProvider) Name ¶ added in v0.8.0
func (p *OIDCProvider) Name() string
Name returns the provider key.
func (*OIDCProvider) SetGuard ¶ added in v1.0.3
func (p *OIDCProvider) SetGuard(g *outbound.Policy)
SetGuard installs the deployment's outbound destination policy on this provider: the operator's additions to the set of hosts its discovery document may name, and the dial-time check on the addresses those hosts resolve to.
It replaces the provider's client, because the dial-time half is a property of the transport and cannot be applied any other way. The end-to-end timeout is unchanged.
func (*OIDCProvider) UserInfo ¶ added in v0.8.0
UserInfo fetches the normalized profile from the discovered userinfo endpoint.
func (*OIDCProvider) VerifyIDToken ¶ added in v0.8.0
func (p *OIDCProvider) VerifyIDToken(ctx context.Context, idToken, expectedNonce string) (*UserInfo, error)
VerifyIDToken validates an OIDC ID token's signature (against the issuer's JWKS) and its iss, aud, exp and nonce claims, returning the normalized profile. It rejects unsigned/HMAC tokens and embedded-key headers (jku/x5u/x5c/jwk).
expectedNonce is the nonce minted for this login attempt and is mandatory. An empty value is rejected rather than read as "skip the nonce check": the nonce is the only claim binding the token to this browser's authorization request, so skipping it would reopen the ID-token / code-injection attack that RFC 9700 §4.5.3 requires the nonce to close. The obligation is discharged by the authorization-code flow in internal/handler/oauth.go, which mints the nonce at /authorize and round-trips it through the HMAC-signed state parameter.
Every failure path returns a nil profile: there is no partial result a caller could mistake for a verified identity.
type Provider ¶
type Provider interface {
// Name returns the provider key used in routes, the signed state parameter
// and the social-account rows, for example "google" or "github".
Name() string
// AuthURL builds the provider's authorization endpoint URL. state is the
// HMAC-signed CSRF/session binding, codeChallenge is the PKCE S256
// challenge, and nonce binds the resulting OIDC ID token to this login
// attempt. Non-OIDC providers ignore nonce, but callers must still pass a
// unique value: [OIDCProvider.VerifyIDToken] rejects a login whose nonce is
// empty. An implementation returns "" when it cannot build a URL, which the
// handler's redirect guard treats as a failure.
AuthURL(state, nonce, codeChallenge string) string
// Exchange swaps an authorization code for tokens, presenting codeVerifier
// as the PKCE proof. It never returns a partially populated TokenResponse:
// a non-nil result means the provider accepted the code.
Exchange(ctx context.Context, code, codeVerifier string) (*TokenResponse, error)
// UserInfo retrieves the profile behind accessToken and normalizes it to
// [UserInfo]. For OIDC issuers this is the fallback path; a verified ID
// token is preferred because it is signed and nonce-bound, while a userinfo
// response is only as trustworthy as the transport.
UserInfo(ctx context.Context, accessToken string) (*UserInfo, error)
}
Provider defines the interface for OAuth2/OIDC providers. Implementations must handle authorization URL construction, authorization code exchange, and user profile retrieval from the provider's API.
type TokenResponse ¶
type TokenResponse struct {
// AccessToken is the provider-issued access token (RFC 6749).
AccessToken string // #nosec G117 -- OAuth2 response field per RFC 6749
// RefreshToken is the provider-issued refresh token, if granted (RFC 6749).
RefreshToken string // #nosec G117 -- OAuth2 response field per RFC 6749
// IDToken is the OIDC ID token, present only for OIDC providers (e.g., Google).
IDToken string
// TokenType is the token type, typically "Bearer".
TokenType string
// ExpiresIn is the access token lifetime in seconds.
ExpiresIn int
}
TokenResponse holds the OAuth2 token exchange response from a provider.
type UserInfo ¶
type UserInfo struct {
// ID is the user's unique identifier at the provider.
ID string
// Email is the user's primary email address.
Email string
// EmailVerified indicates whether the provider has confirmed the email address.
EmailVerified bool
// Name is the user's display name.
Name string
// AvatarURL is a URL to the user's profile picture.
AvatarURL string
// Provider is the name of the OAuth2 provider (e.g., "google", "github").
Provider string
// AuthTime is the instant the provider states it authenticated the user,
// from the OIDC auth_time claim. It is the zero time whenever the provider
// stated none: the claim is OPTIONAL in OIDC Core §2 unless the request sent
// max_age or asked for auth_time as an essential claim, and no non-OIDC
// provider has an equivalent, so most logins leave it zero.
//
// A caller must read the zero value as "not stated" and substitute an
// instant it can vouch for. Passing it on as a timestamp dates the session
// to the Unix epoch, which is the reading internal/service/token.go already
// refuses to emit.
AuthTime time.Time
}
UserInfo holds normalized user profile information retrieved from a provider. Fields are populated to a common schema regardless of the upstream provider.