Handle Web Authentication for Go apps that wish to implement a passwordless solution for users

Overview

WebAuthn Library

GoDoc Go Report Card

This library is meant to handle Web Authentication for Go apps that wish to implement a passwordless solution for users. While the specification is currently in Candidate Recommendation, this library conforms as much as possible to the guidelines and implementation procedures outlined by the document.

Fork

This library is a hard fork of github.com/duo-labs/webauthn however we do not have any affiliation with Duo Labs or any of the authors. This library should not be seen as a representation of them in any form. The intent of this library is to address outstanding issues with that library without having to wait on the maintainers to merge the PR's.

It is distributed under the same 3-Clause BSD license as the original fork, with the only amendment being the additional 3-Clause BSD license attributing license rights to this repository.

Status

This library is still version 0, as per semver rules there may be breaking changes without warning. While we strive to avoid such changes they may be unavoidable.

Quickstart

go get github.com/go-webauthn/webauthn and initialize it in your application with basic configuration values.

Make sure your user model is able to handle the interface functions laid out in webauthn/user.go. This means also supporting the storage and retrieval of the credential and authenticator structs in webauthn/credential.go and webauthn/authenticator.go, respectively.

Initialize the request handler

import (
	"github.com/go-webauthn/webauthn/webauthn"
)

var (
    web *webauthn.WebAuthn
    err error
)

// Your initialization function
func main() {
    web, err = webauthn.New(&webauthn.Config{
        RPDisplayName: "Go Webauthn", // Display Name for your site
        RPID: "go-webauthn.local", // Generally the FQDN for your site
        RPOrigin: "https://login.go-webauthn.local", // The origin URL for WebAuthn requests
        RPIcon: "https://go-webauthn.local/logo.png", // Optional icon URL for your site
    })
    if err != nil {
        fmt.Println(err)
    }
}

Registering an account

func BeginRegistration(w http.ResponseWriter, r *http.Request) {
    user := datastore.GetUser() // Find or create the new user  
    options, sessionData, err := web.BeginRegistration(&user)
    // handle errors if present
    // store the sessionData values 
    JSONResponse(w, options, http.StatusOK) // return the options generated
    // options.publicKey contain our registration options
}

func FinishRegistration(w http.ResponseWriter, r *http.Request) {
    user := datastore.GetUser() // Get the user  
    // Get the session data stored from the function above
    // using gorilla/sessions it could look like this
    sessionData := store.Get(r, "registration-session")
    parsedResponse, err := protocol.ParseCredentialCreationResponseBody(r.Body)
    credential, err := web.CreateCredential(&user, sessionData, parsedResponse)
    // Handle validation or input errors
    // If creation was successful, store the credential object
    JSONResponse(w, "Registration Success", http.StatusOK) // Handle next steps
}

Logging into an account

func BeginLogin(w http.ResponseWriter, r *http.Request) {
    user := datastore.GetUser() // Find the user
    options, sessionData, err := webauthn.BeginLogin(&user)
    // handle errors if present
    // store the sessionData values
    JSONResponse(w, options, http.StatusOK) // return the options generated
    // options.publicKey contain our registration options
}

func FinishLogin(w http.ResponseWriter, r *http.Request) {
    user := datastore.GetUser() // Get the user 
    // Get the session data stored from the function above
    // using gorilla/sessions it could look like this
    sessionData := store.Get(r, "login-session")
    parsedResponse, err := protocol.ParseCredentialRequestResponseBody(r.Body)
    credential, err := webauthn.ValidateLogin(&user, sessionData, parsedResponse)
    // Handle validation or input errors
    // If login was successful, handle next steps
    JSONResponse(w, "Login Success", http.StatusOK)
}

Modifying Credential Options

You can modify the default credential creation options for registration and login by providing optional structs to the BeginRegistration and BeginLogin functions.

Registration modifiers

You can modify the registration options in the following ways:

// Wherever you handle your WebAuthn requests
import (
	"github.com/go-webauthn/webauthn/protocol"
	"github.com/go-webauthn/webauthn/webauthn"
)

var webAuthnHandler webauthn.WebAuthn // init this in your init function

func beginRegistration() {
    // Updating the AuthenticatorSelection options. 
    // See the struct declarations for values
    authSelect := protocol.AuthenticatorSelection{        
		AuthenticatorAttachment: protocol.AuthenticatorAttachment("platform"),
		RequireResidentKey: protocol.ResidentKeyUnrequired(),
        UserVerification: protocol.VerificationRequired
    }

    // Updating the ConveyencePreference options. 
    // See the struct declarations for values
    conveyencePref := protocol.ConveyancePreference(protocol.PreferNoAttestation)

    user := datastore.GetUser() // Get the user  
    opts, sessionData, err webAuthnHandler.BeginRegistration(&user, webauthn.WithAuthenticatorSelection(authSelect), webauthn.WithConveyancePreference(conveyancePref))

    // Handle next steps
}

Login modifiers

You can modify the login options to allow only certain credentials:

// Wherever you handle your WebAuthn requests
import (
	"github.com/go-webauthn/webauthn/protocol"
	"github.com/go-webauthn/webauthn/webauthn"
)

var webAuthnHandler webauthn.WebAuthn // init this in your init function

func beginLogin() {
    // Updating the AuthenticatorSelection options. 
    // See the struct declarations for values
    allowList := make([]protocol.CredentialDescriptor, 1)
    allowList[0] = protocol.CredentialDescriptor{
        CredentialID: credentialToAllowID,
        Type: protocol.CredentialType("public-key"),
    }

    user := datastore.GetUser() // Get the user  

    opts, sessionData, err := webAuthnHandler.BeginLogin(&user, webauthn.wat.WithAllowedCredentials(allowList))

    // Handle next steps
}

Acknowledgements

We graciously acknowledge the original authors of this library github.com/duo-labs/webauthn for their amazing implementation. Without their amazing work this library could not exist.

Issues
  • build(deps): update module github.com/mitchellh/mapstructure to v1.5.0

    build(deps): update module github.com/mitchellh/mapstructure to v1.5.0

    WhiteSource Renovate

    This PR contains the following updates:

    | Package | Type | Update | Change | |---|---|---|---| | github.com/mitchellh/mapstructure | require | minor | v1.4.3 -> v1.5.0 |


    Release Notes

    mitchellh/mapstructure

    v1.5.0

    Compare Source


    Configuration

    📅 Schedule: At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    Rebasing: Renovate will not automatically rebase this PR, because other commits have been found.

    🔕 Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by WhiteSource Renovate. View repository job log here.

    dependencies go 
    opened by renovate[bot] 0
  • revert: remove resident key unrequired method

    revert: remove resident key unrequired method

    This restores the method protocol.ResidentKeyUnrequired() as an alias of the new option. The restored method is CLEARLY marked as deprecated and will be removed in the future.

    opened by james-d-elliott 0
  • feat: discoverable login

    feat: discoverable login

    This adds discoverable login tooling previously known as resident keys. It does so via an overloaded ValidateLogin that retrieves the user object for a given UserHandle if available in the response.

    opened by james-d-elliott 0
  • fix: parse all transports even if unknown

    fix: parse all transports even if unknown

    The spec requires RP's to accept all transports even unregistered/unknown ones. See https://w3c.github.io/webauthn/#dom-authenticatorattestationresponse-transports-slot.

    opened by james-d-elliott 0
  • fix: parse all transports even if unknown

    fix: parse all transports even if unknown

    The spec requires RP's to accept all transports even unregistered/unknown ones. See https://w3c.github.io/webauthn/#dom-authenticatorattestationresponse-transports-slot.

    opened by james-d-elliott 0
  • refactor: use type switch with assignment

    refactor: use type switch with assignment

    This minor refactor utilizes type switch assignments instead of basic switch statements. This results in less allocations. In addition it dumps the usage of fmt.Sprintf to format bytes as a string.

    opened by james-d-elliott 0
  • build(deps): update golang.org/x/crypto digest to 6f7dac9

    build(deps): update golang.org/x/crypto digest to 6f7dac9

    WhiteSource Renovate

    This PR contains the following updates:

    | Package | Type | Update | Change | |---|---|---|---| | golang.org/x/crypto | require | digest | 7b82a4e -> 6f7dac9 |


    Configuration

    📅 Schedule: At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    🔕 Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by WhiteSource Renovate. View repository job log here.

    dependencies go 
    opened by renovate[bot] 0
  • Dependency Dashboard

    Dependency Dashboard

    This issue provides visibility into Renovate updates and their statuses. Learn more

    Open

    These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

    Detected dependencies

    gomod
    go.mod
    • github.com/fxamacker/cbor/v2 v2.4.0
    • github.com/go-webauthn/revoke v0.1.1
    • github.com/golang-jwt/jwt/v4 v4.4.1
    • github.com/google/uuid v1.3.0
    • github.com/mitchellh/mapstructure v1.5.0
    • golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4

    • [ ] Check this box to trigger a request for Renovate to run again on this repository
    opened by renovate[bot] 0
  • fix: implement strict appid checking

    fix: implement strict appid checking

    Intention is to allow the implementation to decide if strict checking is necessary. The spec indicates that some clients may not provide the extension results making this potentially problematic so it should be something that can be turned off.

    In addition we should probably take into consideration the fact that if the ClientExtensionOutputs is not provided that the device itself MAY have authenticated using the appID extension. But this may be a bit more work and security is paramount over compatibility.

    opened by james-d-elliott 0
  • List issues and PRs from upstream that got resolved here

    List issues and PRs from upstream that got resolved here

    It would be nice to have such a list to see what has been fixed and what not. A simple list with cross-reference would be enough I guess. :)

    Just noticed that there is even a second fork you work on as well: https://github.com/authelia/webauthn Could you explain which one is the most up-to-date? Seems like you actively contribute to all of them @james-d-elliott :D

    opened by mainrs 2
Releases(v0.3.1)
A simple passwordless authentication middleware that uses only email as the authentication provider

email auth A simple passwordless authentication middleware that uses only email as the authentication provider. Motivation I wanted to restrict access

Miroslav Šedivý 4 Jan 31, 2022
A simple passwordless proxy authentication middleware using email.

email proxy auth A simple passwordless proxy authentication middleware that uses only email as the authentication provider. Motivation I wanted to res

Miroslav Šedivý 4 Jan 31, 2022
Authelia: an open-source authentication and authorization server providing two-factor authentication

Authelia is an open-source authentication and authorization server providing two

Streato 0 Jan 5, 2022
Authentication Plugin for implementing Form-Based, Basic, Local, LDAP, OpenID Connect, OAuth 2.0, SAML Authentication

Authentication Plugin for implementing Form-Based, Basic, Local, LDAP, OpenID Connect, OAuth 2.0, SAML Authentication

Paul Greenberg 372 May 15, 2022
Authorization and authentication. Learning go by writing a simple authentication and authorization service.

Authorization and authentication. Learning go by writing a simple authentication and authorization service.

Dinesh Bhattarai 0 Jan 30, 2022
A library for performing OAuth Device flow and Web application flow in Go client apps.

oauth A library for Go client applications that need to perform OAuth authorization against a server, typically GitHub.com. Traditionally,

GitHub CLI 326 May 8, 2022
The Single Sign-On Multi-Factor portal for web apps

Authelia is an open-source authentication and authorization server providing two-factor authentication and single sign-on (SSO) for your applications

Authelia 12.9k May 15, 2022
Go-Guardian is a golang library that provides a simple, clean, and idiomatic way to create powerful modern API and web authentication.

❗ Cache package has been moved to libcache repository Go-Guardian Go-Guardian is a golang library that provides a simple, clean, and idiomatic way to

Sanad Haj Yahya 366 May 14, 2022
Package goth provides a simple, clean, and idiomatic way to write authentication packages for Go web applications.

Goth: Multi-Provider Authentication for Go Package goth provides a simple, clean, and idiomatic way to write authentication packages for Go web applic

Mark Bates 3.7k May 16, 2022
Authentication service that keeps you in control without forcing you to be an expert in web security.

Authentication service that keeps you in control without forcing you to be an expert in web security.

Keratin 1.1k Apr 30, 2022
A simple authentication web application in Golang (using jwt)

Simple Authentication WebApp A simple authentication web app in Go (using JWT) Routes Path Method Data /api/v1/auth/register POST {"firstname":,"lastn

Shayan 2 Feb 6, 2022
an SSO and OAuth / OIDC login solution for Nginx using the auth_request module

Vouch Proxy An SSO solution for Nginx using the auth_request module. Vouch Proxy can protect all of your websites at once. Vouch Proxy supports many O

Vouch 1.9k May 18, 2022
sso, aka S.S.Octopus, aka octoboi, is a single sign-on solution for securing internal services

sso See our launch blog post for more information! Please take the SSO Community Survey to let us know how we're doing, and to help us plan our roadma

BuzzFeed 2.9k May 10, 2022
A single sign-on solution based on go-oauth2 / oauth2 and gin-gonic/gin

A single sign-on solution based on go-oauth2 / oauth2 and gin-gonic/gin

yinhuanyi 1 Nov 17, 2021
:closed_lock_with_key: Middleware for keeping track of users, login states and permissions

Permissions2 Middleware for keeping track of users, login states and permissions. Online API Documentation godoc.org Features and limitations Uses sec

Alexander F. Rødseth 456 May 11, 2022
A demo using go and redis to implement a token manager

使用go-redis实现一个令牌管理器 需求描述 假设我们当前的所有服务需要一个第三方的认证,认证形式为:在发送请求的时候带上第三方颁发的令牌,该令牌具有一个时效性 第三方的令牌可以通过某个接口获取,但是该接口做了单位时间内的同一ip的请求频率的限制,因此在并发的场景下,我们需要控制令牌获取接口的频

Yuki Chen 0 Oct 19, 2021
It is a JWT based implement of identity server.

JWTAuth 安裝說明 基本需求 安裝 docker 服務 安裝 OpenSSL 安裝指令 建立 OS 系統的 jwtauth 帳號 sudo useradd -m jwtauth 給予 JWTAuth 帳號可以操作 docker 的權限 sudo usermod -aG docker jwtau

null 0 Nov 30, 2021
This repository contains a set of tools to help you implement IndieAuth, both server and client, in Go.

This repository contains a set of tools to help you implement IndieAuth, both server and client, in Go.

Henrique Dias 9 Mar 2, 2022
OauthMicroservice-cassandraCluster - Implement microservice of oauth using golang and cassandra to store user tokens

implement microservice of oauth using golang and cassandra to store user tokens

Mehdi 1 Jan 24, 2022