oauthprovider

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Sep 16, 2026 License: MIT Imports: 27 Imported by: 0

Documentation

Overview

Package oauthprovider turns Auth-All into an OAuth 2.1 and OpenID Connect authorization server.

A relying party runs the authorization code flow with PKCE, receives an ID token and a signed access token, and reads claims from the userinfo route. The host renders the login page and the consent page. The plugin holds every authorization request as server state, so no request detail travels in a URL.

p := oauthprovider.New(
    oauthprovider.KeyEncryptionKey(key),
    oauthprovider.LoginPath("/sign-in"),
    oauthprovider.ConsentPath("/consent"),
)
auth, err := authall.New(authall.WithStore(s), authall.WithPlugins(p))
mux.Handle("/.well-known/", p.MetadataHandler())

Index

Constants

View Source
const (
	GrantAuthorizationCode = "authorization_code"
	GrantRefreshToken      = "refresh_token"
	GrantClientCredentials = "client_credentials"
)

The grant types the server supports.

View Source
const (
	AuthClientSecretBasic = "client_secret_basic"
	AuthClientSecretPost  = "client_secret_post"
	AuthNone              = "none"
)

The client authentication methods the server supports.

View Source
const (
	PathAuthorize  = "/oauth2/authorize"
	PathToken      = "/oauth2/token"
	PathUserInfo   = "/oauth2/userinfo"
	PathJWKS       = "/oauth2/jwks"
	PathRegister   = "/oauth2/register"
	PathClient     = "/oauth2/register/"
	PathIntrospect = "/oauth2/introspect"
	PathRevoke     = "/oauth2/revoke"
	PathRequest    = "/oauth2/request"
	PathDecide     = "/oauth2/decide"
	PathConsents   = "/oauth2/consents"
	PathClients    = "/oauth2/clients"
)

Route paths of the plugin, relative to the Auth-All base path.

View Source
const (
	ScopeOpenID        = "openid"
	ScopeProfile       = "profile"
	ScopeEmail         = "email"
	ScopeOfflineAccess = "offline_access"
)

The scopes the plugin understands without host configuration.

View Source
const (
	DefaultAccessTokenTTL  = 10 * time.Minute
	DefaultRefreshTokenTTL = 30 * 24 * time.Hour
	DefaultCodeTTL         = time.Minute
	DefaultRequestTTL      = 15 * time.Minute
	DefaultRotationGrace   = 10 * time.Second
	// DefaultDPoPProofWindow bounds the age of an accepted DPoP proof.
	DefaultDPoPProofWindow = 60 * time.Second
)

Default lifetimes.

View Source
const ID = "oauthprovider"

ID is the stable plugin identifier.

Variables

This section is empty.

Functions

This section is empty.

Types

type ClaimMapping

type ClaimMapping struct {
	// Scope grants the claim. An empty value grants it with the profile scope.
	Scope string
	// Claim is the claim name at the userinfo route.
	Claim string
	// Field is the name of the host-declared user field.
	Field string
}

ClaimMapping publishes a host-declared user field as a claim under a scope. The field must be a user field that the host declared with Returned set.

type ClaimsFunc

type ClaimsFunc func(user *store.User, scopes []string) map[string]any

ClaimsFunc adds claims to the userinfo response. It receives the granted scopes, and it must return no reserved claim name.

type Option

type Option func(*Plugin)

Option configures the plugin.

func AccessTokenTTL

func AccessTokenTTL(d time.Duration) Option

AccessTokenTTL sets the access token lifetime.

func Algorithm

func Algorithm(name string) Option

Algorithm selects the signing algorithm. The default is ES256. A relying party that accepts RS256 only needs RS256.

func AllowDynamicRegistration

func AllowDynamicRegistration() Option

AllowDynamicRegistration opens the RFC 7591 registration route. A client that registers through it manages itself with the RFC 7592 registration access token.

func AllowPlainHTTP

func AllowPlainHTTP(hosts ...string) Option

AllowPlainHTTP names the hosts that may register a plain http redirect URI. A self-hosted deployment without TLS needs it. Loopback and a private-use scheme need no entry.

func Claims

func Claims(mappings ...ClaimMapping) Option

Claims maps host-declared user fields to claims.

func ClaimsFrom

func ClaimsFrom(f ClaimsFunc) Option

ClaimsFrom adds a function that returns further claims.

func Clients

func Clients(clients ...StaticClient) Option

Clients declares the static first-party clients.

func CodeTTL

func CodeTTL(d time.Duration) Option

CodeTTL sets the authorization code lifetime.

func ConsentPath

func ConsentPath(path string) Option

ConsentPath is the host page that asks for consent.

func KeyEncryptionKey

func KeyEncryptionKey(key []byte) Option

KeyEncryptionKey supplies the 32 bytes that wrap every signing key at rest. The plugin refuses to register without it.

func LoginPath

func LoginPath(path string) Option

LoginPath is the host page that authenticates a user. The authorize route redirects to it with the identifier of the authorization request.

func RefreshTokenTTL

func RefreshTokenTTL(d time.Duration) Option

RefreshTokenTTL sets the refresh token lifetime.

func RequestTTL

func RequestTTL(d time.Duration) Option

RequestTTL sets the lifetime of an authorization request. It bounds how long the host pages have to complete the flow.

func Resources

func Resources(resources ...Resource) Option

Resources declares the protected resources a client may name.

func RotationGrace

func RotationGrace(d time.Duration) Option

RotationGrace sets the window in which a rotated refresh token answers a retry with the same successor pair.

func Scopes

func Scopes(names ...string) Option

Scopes replaces the scopes the server offers.

type Plugin

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

Plugin is the OAuth provider plugin.

func New

func New(opts ...Option) *Plugin

New returns the OAuth provider plugin.

func (*Plugin) Claims

func (p *Plugin) Claims(bearer string) bool

Claims implements plugin.CredentialResolver. It looks at the shape of the value only, so the check makes no database call. An access token of this server is a compact JWS with the at+jwt type.

func (*Plugin) Cleanup

func (p *Plugin) Cleanup(ctx context.Context) (int, error)

Cleanup removes the spent and expired rows of the plugin. The host calls it, because Auth-All runs no background work of its own.

func (*Plugin) ID

func (p *Plugin) ID() string

ID implements plugin.Plugin.

func (*Plugin) MetadataHandler

func (p *Plugin) MetadataHandler() http.Handler

MetadataHandler serves the authorization server metadata of RFC 8414 and the OpenID Connect discovery document. The host mounts it at the origin root, because the well-known location lives there and a plugin route cannot reach it:

mux.Handle("/.well-known/", provider.MetadataHandler())

func (*Plugin) Register

func (p *Plugin) Register(r *plugin.Registry) error

Register implements plugin.Plugin.

func (*Plugin) Resolve

func (p *Plugin) Resolve(ctx context.Context, bearer string) (*plugin.Principal, error)

Resolve implements plugin.CredentialResolver.

The resolver accepts a token whose audience is the issuer itself, and it rejects a token that names another resource server. Without that test, a token a third-party relying party holds would open the host API.

func (*Plugin) ResolveRequest

func (p *Plugin) ResolveRequest(ctx context.Context, bearer string, r *http.Request) (*plugin.Principal, error)

ResolveRequest implements plugin.RequestResolver. It enforces the DPoP proof of a bound token, which the bearer value alone cannot carry.

func (*Plugin) Rotate

func (p *Plugin) Rotate(ctx context.Context) error

Rotate issues a new signing key and retires every earlier key. The host calls it, because Auth-All runs no background work of its own. The retired key stays in the published key set, so a relying party with a cached key set keeps verifying the tokens it holds.

type Resource

type Resource struct {
	// Identifier is the absolute URI of the resource. It carries no fragment.
	Identifier string
	// Scopes bounds the scopes an access token for this resource may carry. An
	// empty value allows the configured scopes of the server.
	Scopes []string
	// AccessTokenTTL overrides the server lifetime for this resource.
	AccessTokenTTL time.Duration
}

Resource is one protected resource that a client names with the resource parameter of RFC 8707. The identifier becomes the aud claim of the access token.

type StaticClient

type StaticClient struct {
	// ClientID identifies the client.
	ClientID string
	// Secret authenticates a confidential client. An empty value declares a
	// public client, which must use PKCE and holds no secret.
	Secret string
	// AuthMethod names how the client authenticates at the token endpoint. The
	// default of a confidential client is client_secret_basic. The server
	// enforces the named method, so a leaked secret cannot arrive another way.
	AuthMethod string
	// Name appears on the consent page of another client of the same user.
	Name string
	// RedirectURIs holds the exact registered values.
	RedirectURIs []string
	// Scopes bounds what the client may request. An empty value allows the
	// configured scopes of the server.
	Scopes []string
	// GrantTypes bounds the grants. The default is authorization_code and
	// refresh_token.
	GrantTypes []string
	// DPoPRequired refuses a bearer presentation of a token of this client.
	DPoPRequired bool
}

StaticClient is a first-party client declared in host source. It holds no row, so no runtime route edits it and it needs no consent.

Jump to

Keyboard shortcuts

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