webauthn

package module
v1.1.5 Latest Latest
Warning

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

Go to latest
Published: Aug 12, 2023 License: MIT Imports: 15 Imported by: 0

README

go-webauthn

Go server-side library for WebAuthn registration and verification.

Installation

go get github.com/spiretechnology/go-webauthn

Getting Started

1. Create a credential store

When users register credentials, they need to be stored somewhere. You can store credentials anywhere you'd like, as long as you implement the webauthn.CredentialStore interface.

type myCredentialStore struct {}

func (s *myCredentialStore) GetCredentials(ctx context.Context, user webauthn.User) ([]webauthn.Credential, error) {
    // ...
}

func (s *myCredentialStore) GetCredential(ctx context.Context, user webauthn.User, credentialID []byte) (*webauthn.Credential, error) {
    // ...
}

func (s *myCredentialStore) StoreCredential(ctx context.Context, user webauthn.User, credential webauthn.Credential, meta webauthn.CredentialMeta) error {
    // ...
}

Make sure to store all the fields provided in the webauthn.Credential struct in your database: ID, Type, PublicKey, and PublicKeyAlg.

2. Setup a webauthn.WebAuthn instance

Create a WebAuthn instance with your relying party information and credential store.

wa := webauthn.New(webauthn.Options{
    RP:          webauthn.RelyingParty{ID: "mycompany.com", Name: "My Company"},
    Credentials: &myCredentialStore{},
})

Registration Example

1. Create a registration challenge

When a user sends a request to register a WebAuthn credential, you'll need to generate a registration challenge and send it to the client. You can do this with the CreateRegistration method.

// Create a registration challenge
challenge, err := wa.CreateRegistration(ctx, webauthn.User{
    ID:          "123",      // Unique ID for the user (eg. database ID)
    Name:        "johndoe",  // Username or email
    DisplayName: "John Doe", // User's full name
})

// Marshal `challenge` to JSON and send it to the client
// ...

The challenge value returned is JSON-serializable and can be sent to the client without any additional processing or encoding.

2. Verify the registration response

When the user sends back a response to the registration challenge, you can verify it with the VerifyRegistration method.

// Unmarshal the user's response from JSON
var response webauthn.RegistrationResponse
// ...

// Verify the registration response
user := webauthn.User{ /* same user as before */ }
result, err := wa.VerifyRegistration(ctx, user, response)

Authentication Example

1. Create an authentication challenge

When a user sends a request to authenticate with a WebAuthn credential, you'll generate an authentication challenge and send it to the client. You can do this with the CreateAuthentication method.

// Create an authentication challenge
user := webauthn.User{ /* same user as before */ }
challenge, err := wa.CreateAuthentication(ctx, user)

// Marshal `challenge` to JSON and send it to the client
// ...
2. Verify the authentication response

When the user sends back a response to the authentication challenge, you can verify it with the VerifyAuthentication method.

// Unmarshal the user's response from JSON
var response webauthn.AuthenticationResponse
// ...

// Verify the authentication response
user := webauthn.User{ /* same user as before */ }
result, err := wa.AuthenticationRegistration(ctx, user, response)

Client-side processing

For both registration and authentication, the client is responsible for requesting challenges from the server, and responding to those challenges.

We recommend using our js-webauthn library to handle the client-side flow for you. That library is designed to work with this one.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AllowedCredential

type AllowedCredential struct {
	Type string `json:"type"`
	ID   string `json:"id"`
}

AllowedCredential is a credential that is allowed to be used for authentication.

type AuthenticationChallenge

type AuthenticationChallenge struct {
	Token            string              `json:"token"`
	Challenge        string              `json:"challenge"`
	RPID             string              `json:"rpId"`
	AllowCredentials []AllowedCredential `json:"allowCredentials"`
}

AuthenticationChallenge is the challenge that is sent to the client to initiate an authentication ceremony.

type AuthenticationResponse

type AuthenticationResponse struct {
	Token        string                         `json:"token"`
	Challenge    string                         `json:"challenge"`
	CredentialID string                         `json:"credentialId"`
	Response     AuthenticatorAssertionResponse `json:"response"`
}

AuthenticationResponse is the response sent back by the client after an authentication ceremony.

type AuthenticationResult

type AuthenticationResult struct {
	Credential Credential
}

AuthenticationResult contains the results of verifying the authentication response.

type AuthenticatorAssertionResponse

type AuthenticatorAssertionResponse struct {
	AuthenticatorData string  `json:"authenticatorData"`
	ClientDataJSON    string  `json:"clientDataJSON"`
	Signature         string  `json:"signature"`
	UserHandle        *string `json:"userHandle"`
}

AuthenticatorAssertionResponse is the internal response value send by the client in response to an authentication ceremony.

func (*AuthenticatorAssertionResponse) Decode

type AuthenticatorAttestationResponse

type AuthenticatorAttestationResponse struct {
	ClientDataJSON    string `json:"clientDataJSON"`
	AttestationObject string `json:"attestationObject"`
}

AuthenticatorAttestationResponse is the internal response value send by the client in response to a registration ceremony.

func (*AuthenticatorAttestationResponse) Decode

type Credential

type Credential struct {
	// ID is the `rawId` of the credential, as defined in the WebAuthn spec.
	ID []byte
	// Type is the `type` of the credential, as defined in the WebAuthn spec. Always "public-key".
	Type string
	// PublicKey is the `publicKey` of the credential, as defined in the WebAuthn spec.
	PublicKey []byte
	// PublicKeyAlg is the `publicKeyAlg` of the credential, as defined in the WebAuthn spec.
	// See `PublicKeyType` for supported values.
	PublicKeyAlg int
}

Credential represents a registered credential.

type CredentialMeta added in v1.0.1

type CredentialMeta struct {
	// Authenticator is the model of the authenticator used to create this credential. May be nil.
	Authenticator *authenticators.Authenticator
}

CredentialMeta contains metadata about a credential. Storing this information is not needed for the authentication flow, but may be useful for other purposes.

type Credentials

type Credentials interface {
	GetCredentials(ctx context.Context, user User) ([]Credential, error)
	GetCredential(ctx context.Context, user User, credentialID []byte) (*Credential, error)
	StoreCredential(ctx context.Context, user User, credential Credential, meta CredentialMeta) error
}

Credentials defines the interface for storing registered credentials.

type Options

type Options struct {
	RP             RelyingParty
	Codec          codec.Codec
	PublicKeyTypes []pubkey.KeyType
	Credentials    Credentials
	Tokener        Tokener
	ChallengeFunc  func() (challenge.Challenge, error)
}

type RegistrationChallenge

type RegistrationChallenge struct {
	Token            string                 `json:"token"`
	Challenge        string                 `json:"challenge"`
	RP               RelyingParty           `json:"rp"`
	User             User                   `json:"user"`
	PubKeyCredParams []spec.PubKeyCredParam `json:"pubKeyCredParams"`
}

RegistrationChallenge is the challenge that is sent to the client to initiate a registration ceremony.

type RegistrationResponse

type RegistrationResponse struct {
	Token        string                           `json:"token"`
	Challenge    string                           `json:"challenge"`
	CredentialID string                           `json:"credentialId"`
	Response     AuthenticatorAttestationResponse `json:"response"`
}

RegistrationResponse is the response sent back by the client after a registration ceremony.

type RegistrationResult

type RegistrationResult struct {
	Credential Credential
	Meta       CredentialMeta
}

RegistrationResult contains the results of verifying the registration respose.

type RelyingParty

type RelyingParty struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

RelyingParty is the ID and name or the relying party.

type Tokener added in v1.1.0

type Tokener interface {
	CreateToken(challenge challenge.Challenge, user User) (string, error)
	VerifyToken(token string, challenge challenge.Challenge, user User) error
}

Tokener defines the interface for creating tokens to ensure the authenticity of registration and authentication responses from users.

func NewJwtTokener added in v1.1.0

func NewJwtTokener(signer jwt.Signer, verifier jwt.Verifier) Tokener

NewJwtTokener creates a new tokener that issues JWT tokens.

type User

type User struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	DisplayName string `json:"displayName"`
}

User contains the details of a user to be registered or authenticated. Conforms to the WebAuthn spec.

type WebAuthn

type WebAuthn interface {
	CreateRegistration(ctx context.Context, user User) (*RegistrationChallenge, error)
	VerifyRegistration(ctx context.Context, user User, res *RegistrationResponse) (*RegistrationResult, error)
	CreateAuthentication(ctx context.Context, user User) (*AuthenticationChallenge, error)
	VerifyAuthentication(ctx context.Context, user User, res *AuthenticationResponse) (*AuthenticationResult, error)
}

func New

func New(options Options) WebAuthn

Directories

Path Synopsis
internal
pkg

Jump to

Keyboard shortcuts

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