GithubHelp home page GithubHelp logo

koesie10 / webauthn Goto Github PK

View Code? Open in Web Editor NEW
164.0 4.0 17.0 76 KB

Go package for easy WebAuthn integration

License: MIT License

Go 97.44% JavaScript 2.56%
webauthn passwordless login authentication 2fa 2factor

webauthn's Introduction

webauthn : Web Authentication API in Go

Overview GoDoc Build Status

This project provides a low-level and a high-level API to use the Web Authentication API (WebAuthn).

Demo

Install

go get github.com/koesie10/webauthn

Attestation

By default, this library does not support any attestation statement formats. To use the default attestation formats, you will need to import github.com/koesie10/webauthn/attestation or any of its subpackages if you would just like to support some attestation statement formats.

Please note that the Android SafetyNet attestation statement format depends on gopkg.in/square/go-jose.v2, which means that this package will be imported when you import either github.com/koesie10/webauthn/attestation or github.com/koesie10/webauthn/attestation/androidsafetynet.

High-level API

The high-level API can be used with the net/http package and simplifies the low-level API. It is located in the webauthn subpackage. It is intended for use with e.g. fetch or XMLHttpRequest JavaScript clients.

First, make sure your user entity implements User. Then, create a new entity implements Authenticator that stores each authenticator the user registers.

Then, either make your existing repository implement AuthenticatorStore or create a new repository.

Finally, you can create the main WebAuthn struct supplying the Config options:

w, err := webauthn.New(&webauthn.Config{
    // A human-readable identifier for the relying party (i.e. your app), intended only for display.
    RelyingPartyName:   "webauthn-demo",
    // Storage for the authenticator.
    AuthenticatorStore: storage,
})		

Then, you can use the methods defined, such as StartRegistration to handle registration and login. Every handler requires a Session, which stores intermediate registration/login data. If you use gorilla/sessions, use webauthn.WrapMap(session.Values). Read the documentation for complete information on what parameters need to be passed and what values are returned.

For example, a handler for finishing the registration might look like this:

func (r *http.Request, rw http.ResponseWriter) {
    ctx := r.Context()

    // Get the user in some way, in this case from the context
    user, ok := UserFromContext(ctx)
    if !ok {
        rw.WriteHeader(http.StatusForbidden)
        return
    }

    // Get or create a session in some way, in this case from the context
    sess := SessionFromContext(ctx)

    // Then call FinishRegistration to register the authenticator to the user
    h.webauthn.FinishRegistration(r, rw, user, webauthn.WrapMap(sess))
}

A complete demo application using the high-level API which implements all of these interfaces and stores data in memory is available here.

JavaScript examples

This class is an example that can be used to handle the registration and login phases. It can be used as follows:

const w = new WebAuthn();

// Registration
w.register().then(() => {
    alert('This authenticator has been registered.');
}).catch(err => {
    console.error(err);
    alert('Failed to register: ' + err);
});

// Login
w.login().then(() => {
    alert('You have been logged in.');
}).catch(err => {
    console.error(err);
    alert('Failed to login: ' + err);
});

Or, with latest async/await paradigm:

const w = new WebAuthn();

// Registration
try {
    await w.register();
    alert('This authenticator has been registered.');
} catch (err) {
    console.error(err)
    alert('Failed to register: ' + err);
}

// Login
try {
    await w.login();
    alert('You have been logged in.');
} catch(err) {
    console.error(err);
    alert('Failed to login: ' + err);
}

Low-level API

The low-level closely resembles the specification and the high-level API should be preferred. However, if you would like to use the low-level API, the main entry points are:

License

MIT.

webauthn's People

Contributors

alkorin avatar erjanmx avatar koesie10 avatar saniales avatar tonyd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

webauthn's Issues

Unsupported format self attestation on Macbook

Hi,

This issue was previously submitted on webauthn-demo repo. i think it is more relevant to be issued here


When trying this demo via touch id on macbook, I got this error:

Failed to register: Error: Bad Request

Debugging on registration.go: line 128 showing:

unsupported format self attestation

I believe it requires packed + self (surrogate) attestation for this. There's article for the implementation by Ackermann Yuriy here

AuthenticatorStore GetAuthenticator definition

I have a question about the definition of id in GetAuthenticator (

// GetAuthenticator gets a single Authenticator by the given id, as returned by Authenticator.WebAuthID.
)

Should this not state WebAuthCredentialID is the reference ID ? Since (I assume) Authenticator.WebAuthID is inherently the same as User.WebAuthID and thus by definition using WebAuthID be expected to return multiple authenticators (i.e. behavior of GetAuthenticators(user User) and the only way to retrieve one authenticator would be using WebAuthCredentialID.

The attestation format none is unknown

#koesie10/webauthn-demo:1

When I was trying to register with Windows Hello, I got the following error:

image

then I added these code:

{
	Type:      protocol.PublicKeyCredentialTypePublicKey,
	Algorithm: protocol.RS256,
},

in PubKeyCredParams:

PubKeyCredParams: []protocol.PublicKeyCredentialParameters{
{
Type: protocol.PublicKeyCredentialTypePublicKey,
Algorithm: protocol.ES256,
},
},

Then the error disappeared, but I got an error while finishing the registration (running WebAuthn.ParseAndFinishRegistration()) at line 132:

func (a Attestation) IsValid(relyingPartyID string, clientDataHash []byte) error {
// Check the auth data, i.e. steps 9-11
if err := a.AuthData.IsValid(relyingPartyID); err != nil {
return err
}
// 13. Determine the attestation statement format by performing a USASCII case-sensitive match on fmt against the set
// of supported WebAuthn Attestation Statement Format Identifier values.
format, ok := attestationFormats[a.Fmt]
if !ok {
return ErrUnsupportedAttestationFormat.WithDebugf("The attestation format %q is unknown", a.Fmt)
}
// 14. Verify that attStmt is a correct attestation statement, conveying a valid attestation signature, by using the
// attestation statement format fmt’s verification procedure given attStmt, authData and the hash of the serialized
// client data computed in step 7.
if err := format(a, clientDataHash); err != nil {
return err
}
// NOTE: However, if permitted by policy, the Relying Party MAY register the credential ID and credential public
// key but treat the credential as one with self attestation (see §6.4.3 Attestation Types). If doing so, the
// Relying Party is asserting there is no cryptographic proof that the public key credential has been generated
// by a particular authenticator model. See [FIDOSecRef] and [UAFProtocol] for a more detailed discussion.
return nil
}

the a.Fmt was none.

When I added the code after line 131, in the if statement:

fmt.Println(a)

I got:

{none {[73 150 13 229 136 14 140 104 116 52 23 15 100 118 96 91 143 228 174 185 162 134 50 199 153 92 243 186 131 29 151 99] 69 0 {[8 152 112 88 202 220 75 129 182 225 48 222 80 220 190 150] [128 130 138 131 9 189 56 216 26 246 190 158 248 45 191 164 84 166 213 131 62 181 18 46 113 12 28 137 121 0 109 91] 0xc000591f20} [73 150 13 229 136 14 140 104 116 52 23 15 100 118 96 91 143 228 174 185 162 134 50 199 153 92 243 186 131 29 151 99 69 0 0 0 0 8 152 112 88 202 220 75 129 182 225 48 222 80 220 190 150 0 32 128 130 138 131 9 189 56 216 26 246 190 158 248 45 191 164 84 166 213 131 62 181 18 46 113 12 28 137 121 0 109 91 165 1 2 3 38 32 1 33 88 32 217 145 48 116 108 253 35 25 94 92 211 105 11 171 14 210 166 187 234 244 11 98 139 121 164 113 221 85 67 162 231 185 34 88 32 247 33 217 249 92 143 250 186 2 86 77 210 126 150 173 2 255 141 59 201 39 82 166 104 190 125 179 18 199 101 148 97]} map[]}

Chrome 121.0.6167.86.

Update: Same problem on Firefox 116.0.3 (64 bit)

Move attestation formats to separate package?

Hi! Thanks for making github.com/koesie10/webauthn.

Currently, the only reason to depend on gopkg.in/square/go-jose.v2 is to support Android SafetyNet Attestation Statements. Since some folks don't care about attestation, would you be open to moving the code for attestation formats (attestation_android_safetynet.go, attestation_fido.go, and attestation_packed.go) to a separate package? People who want attestation support could import this package from package main with a blank identifier (similar to how SQL drivers are registered). Then the people who don't want attestation wouldn't need dependencies like gopkg.in/square/go-jose.v2.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.