Documentation
¶
Overview ¶
Package passkeys provides support for creating and authenticating WebAuthn passkeys.
Index ¶
- Constants
- Variables
- type BeginRegistrationRequest
- type EmailValidator
- type Handler
- func (h *Handler) BeginDiscoverableAuthentication(rw http.ResponseWriter, _ *http.Request)
- func (h *Handler) BeginRegistration(rw http.ResponseWriter, r *http.Request)
- func (h *Handler) FinishAuthentication(rw http.ResponseWriter, r *http.Request)
- func (h *Handler) FinishRegistration(rw http.ResponseWriter, r *http.Request)
- func (h *Handler) VerifyAuthentication(rw http.ResponseWriter, r *http.Request)
- type HandlerOption
- func WithEmailValidator(validator EmailValidator) HandlerOption
- func WithLogger(logger *slog.Logger) HandlerOption
- func WithMediation(mediation protocol.CredentialMediationRequirement) HandlerOption
- func WithRegistrationOptions(opts ...webauthn.RegistrationOption) HandlerOption
- func WithSessionCookieScopeAndDuration(ck cookies.ScopeAndDuration) HandlerOption
- type JWTCookieLoginManager
- type LoginManager
- type RAMUserDatabase
- func (sm RAMUserDatabase) Authenticated(tmpKey string) (sessionData *webauthn.SessionData, err error)
- func (sm RAMUserDatabase) Authenticating(sessionData *webauthn.SessionData) (tmpKey string, err error)
- func (um RAMUserDatabase) Lookup(userID UserID) (*User, error)
- func (sm RAMUserDatabase) Registered(tmpKey string) (user *User, sessionData *webauthn.SessionData, err error)
- func (sm RAMUserDatabase) Registering(user *User, sessionData *webauthn.SessionData) (tmpKey string, exists bool, err error)
- func (um RAMUserDatabase) Store(user *User) error
- type SessionManager
- type User
- func (u *User) AddCredential(cred webauthn.Credential)
- func (u *User) ID() UserID
- func (u User) ParseUID(uid string) (UserID, error)
- func (u *User) UpdateCredential(cred webauthn.Credential) bool
- func (u *User) WebAuthnCredentials() []webauthn.Credential
- func (u *User) WebAuthnDisplayName() string
- func (u *User) WebAuthnID() []byte
- func (u *User) WebAuthnName() string
- type UserDatabase
- type UserID
- type WebAuthn
Constants ¶
const ( // AuthenticationCookie is set during the login/authentication // webauthn flow (set in Begin and cleared in Finish). AuthenticationCookie = cookies.Secure("webauthn_authentication") // RegistrationCookie is set during the registration webauthn flow // (set in Begin and cleared in Finish). RegistrationCookie = cookies.Secure("webauthn_registration") )
Variables ¶
var BeginDiscoverableAuthenticationEndpoint = jsonapi.Endpoint[struct{}, *protocol.CredentialAssertion]{}
BeginDiscoverableAuthenticationEndpoint represents the endpoint for beginning the authentication using a discoverable passkey. The user's identity will be determined by the user handle provided in the request. The response will contain the options for the authentication request.
var BeginRegistrationEndpoint = jsonapi.Endpoint[ BeginRegistrationRequest, *protocol.PublicKeyCredentialCreationOptions]{}
BeginRegistrationEndpoint represents the endpoint for beginning the registration process.
var FinishAuthenticationEndpoint = jsonapi.Endpoint[struct{}, struct{}]{}
FinishAuthenticationEndpoint represents the endpoint for finishing the authentication process. It expects a request with a JSON body containing the verification data as expected by the webauthn.FinishDiscoverableLogin method, this method parses the request directly and hence the ParseRequest is not used. The response on success is simply a http.StatusOK with an empty body. Strictly speaking this variable is not used but serves to document the endpoint.
var FinishRegistrationEndpoint = jsonapi.Endpoint[struct{}, struct{}]{}
FinishRegistrationEndpoint represents the endpoint for finishing the registration process. It expects a request with a JSON body containing the verification data as expected by the webauthn.FinishRegistration method, this method parses the request directly and hence the ParseRequest is not used. The response on success is simply a http.StatusOK with an empty body. Strictly speaking this variable is not used but serves to document the endpoint.
var VerifyAuthenticationEndpoint = jsonapi.Endpoint[struct{}, struct{}]{}
VerifyAuthenticationEndpoint represents the endpoint for verifying the authentication of a user. It expects the user to be authenticated and to have an entry in the user database.
Functions ¶
This section is empty.
Types ¶
type BeginRegistrationRequest ¶
type BeginRegistrationRequest struct {
Email string `json:"email"`
DisplayName string `json:"display_name"`
}
BeginRegistrationRequest represents the request body for beginning the registration process, the client should send a JSON object with the user's email address and display name.
type EmailValidator ¶
EmailValidator defines an interface for validating email addresses.
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler provides http Handlers that implement passkey registration and authentication using the WebAuthn protocol. These endpoints accept JSON requests and responses.
func NewHandler ¶
func NewHandler(w WebAuthn, sm SessionManager, um UserDatabase, lm LoginManager, opts ...HandlerOption) *Handler
NewHandler creates a new passkeys handler with the provided WebAuthn implementation, session and user managers.
func (*Handler) BeginDiscoverableAuthentication ¶
func (h *Handler) BeginDiscoverableAuthentication(rw http.ResponseWriter, _ *http.Request)
func (*Handler) BeginRegistration ¶
func (h *Handler) BeginRegistration(rw http.ResponseWriter, r *http.Request)
BeginRegistration starts the registration process for a user. It expects a request with a JSON body containing the user's email address.
func (*Handler) FinishAuthentication ¶
func (h *Handler) FinishAuthentication(rw http.ResponseWriter, r *http.Request)
func (*Handler) FinishRegistration ¶
func (h *Handler) FinishRegistration(rw http.ResponseWriter, r *http.Request)
func (*Handler) VerifyAuthentication ¶
func (h *Handler) VerifyAuthentication(rw http.ResponseWriter, r *http.Request)
type HandlerOption ¶
type HandlerOption func(*options)
HandlerOption represents an option for configuring the Handler.
func WithEmailValidator ¶
func WithEmailValidator(validator EmailValidator) HandlerOption
WithEmailValidator sets the email validator for the handler.
func WithLogger ¶
func WithLogger(logger *slog.Logger) HandlerOption
WithLogger sets the logger for the handler. The default is discard log output.
func WithMediation ¶
func WithMediation(mediation protocol.CredentialMediationRequirement) HandlerOption
WithMediation sets the mediation requirement for the handler.
func WithRegistrationOptions ¶
func WithRegistrationOptions(opts ...webauthn.RegistrationOption) HandlerOption
WithRegistrationOptions sets the registration options for the handler.
func WithSessionCookieScopeAndDuration ¶
func WithSessionCookieScopeAndDuration(ck cookies.ScopeAndDuration) HandlerOption
WithSessionCookieScopeAndDuration sets the session cookie's scope (domain, path) and duration.
type JWTCookieLoginManager ¶
type JWTCookieLoginManager struct {
// LoginCookie is set when the user has successfully logged in using
// webauthn and is used to inform the server that the user has
// successfully logged in
LoginCookie cookies.Secure // initialized as cookies.T("webauthn_login")
// contains filtered or unexported fields
}
JWTCookieLoginManager implements the LoginManager interface using JWTs stored in cookies.
func NewJWTCookieLoginManager ¶
func NewJWTCookieLoginManager(signer jwtutil.Signer, issuer string, cookie cookies.ScopeAndDuration) JWTCookieLoginManager
NewJWTCookieLoginManager creates a new JWTCookieLoginManager instance.
func (JWTCookieLoginManager) AuthenticateUser ¶
func (m JWTCookieLoginManager) AuthenticateUser(r *http.Request) (UserID, error)
func (JWTCookieLoginManager) UserAuthenticated ¶
func (m JWTCookieLoginManager) UserAuthenticated(r *http.Request, rw http.ResponseWriter, user UserID) error
type LoginManager ¶
type LoginManager interface {
// UserAuthenticated is called after a user has successfully logged in with a passkey.
// It should be used to set a session Cookie, or a JWT token to be validated
// on subsequent requests. The expiration parameter indicates how long the
// login session should be valid.
UserAuthenticated(r *http.Request, rw http.ResponseWriter, user UserID) error
// AuthenticateUser is called to validate the user based on the request.
// It should return the UserID of the authenticated user or an error if authentication fails.
AuthenticateUser(r *http.Request) (UserID, error)
}
LoginManager defines the interface for managing logged in users who have authenticated using a passkey.
type RAMUserDatabase ¶
type RAMUserDatabase struct {
// contains filtered or unexported fields
}
func NewRAMUserDatabase ¶
func NewRAMUserDatabase() *RAMUserDatabase
func (RAMUserDatabase) Authenticated ¶
func (sm RAMUserDatabase) Authenticated(tmpKey string) (sessionData *webauthn.SessionData, err error)
func (RAMUserDatabase) Authenticating ¶
func (sm RAMUserDatabase) Authenticating(sessionData *webauthn.SessionData) (tmpKey string, err error)
func (RAMUserDatabase) Registered ¶
func (sm RAMUserDatabase) Registered(tmpKey string) (user *User, sessionData *webauthn.SessionData, err error)
func (RAMUserDatabase) Registering ¶
type SessionManager ¶
type SessionManager interface {
// Used when creating a new passkey.
Registering(user *User, sessionData *webauthn.SessionData) (tmpKey string, exists bool, err error)
Registered(tmpKey string) (user *User, sessionData *webauthn.SessionData, err error)
// Used when authenticating a passkey.
Authenticating(sessionData *webauthn.SessionData) (tmpKey string, err error)
Authenticated(tmpKey string) (sessionData *webauthn.SessionData, err error)
}
SessionManager is the interface used by passkeys.Server to manage state between 'begin' and 'finish' registration and authentication requests.
type User ¶
type User struct {
// contains filtered or unexported fields
}
User represents a user that registers to use a passkey and implements webauthn.User
func (*User) AddCredential ¶
func (u *User) AddCredential(cred webauthn.Credential)
Implements webauthn.User.
func (User) ParseUID ¶
ParseUID parses a string representation of a UserID and returns the UserID. It returns an error if the string cannot be parsed. It is required to parse a UserID into the implementation of UserID used by the User struct.
func (*User) UpdateCredential ¶
func (u *User) UpdateCredential(cred webauthn.Credential) bool
UpdateCredential updates an existing credential for the user.
func (*User) WebAuthnCredentials ¶
func (u *User) WebAuthnCredentials() []webauthn.Credential
Implements webauthn.User.
func (*User) WebAuthnDisplayName ¶
Implements webauthn.User.
type UserDatabase ¶
type UserDatabase interface {
// Store persists the user in the database, using the user.ID().String() as the key.
Store(user *User) error
// Lookup retrieves a user using the UUID it was original created with.
Lookup(uid UserID) (*User, error)
}
UserDatabase is an interface for a user database that supports registering and authenticating passkeys.
type UserID ¶
type UserID interface {
String() string // Returns a string representation of the user ID that can be used usable as a key in a map. String should return the same value as MarshalText and hence UnmarshalText(String()) == UnmarshalText(MarshalText()).
UnmarshalBinary([]byte) error // Converts a byte slice to a UserID.
MarshalText() ([]byte, error) // Converts the UserID to base64.RawURLEncoding representation.
UnmarshalText([]byte) error // Converts a base64.RawURLEncoding text representation to a UserID.
}
UserID is used to uniquely identify users in the passkey system. It must be a cryptographically secure randomly generated value, (eg. 64 bytes read crypto.rand.Reader).
func UserIDFromBytes ¶
UserIDFromBytes creates a UserID from a byte slice.
func UserIDFromString ¶
UserIDFromString creates a UserID from a base64.RawURLEncoding string.
type WebAuthn ¶
type WebAuthn interface {
BeginMediatedRegistration(user webauthn.User, mediation protocol.CredentialMediationRequirement, opts ...webauthn.RegistrationOption) (creation *protocol.CredentialCreation, session *webauthn.SessionData, err error)
FinishRegistration(user webauthn.User, session webauthn.SessionData, r *http.Request) (*webauthn.Credential, error)
BeginDiscoverableMediatedLogin(mediation protocol.CredentialMediationRequirement, opts ...webauthn.LoginOption) (*protocol.CredentialAssertion, *webauthn.SessionData, error)
FinishPasskeyLogin(handler webauthn.DiscoverableUserHandler, session webauthn.SessionData, request *http.Request) (user webauthn.User, credential *webauthn.Credential, err error)
}
WebAuthn defines the subset of webauthn.WebAuthn used by this package.