Skip to content

Commit

Permalink
Use library discoverable login
Browse files Browse the repository at this point in the history
We don't need to drop to protocol for that.

Fix the timeout defaulting to zero, breaking logins
  • Loading branch information
lstoll committed Mar 9, 2024
1 parent 63d37df commit 41fef41
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 31 deletions.
21 changes: 14 additions & 7 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io"
"io/fs"
"log"
"log/slog"
"net"
"net/http"
Expand Down Expand Up @@ -179,8 +180,10 @@ func serve(ctx context.Context, db *DB, issuer issuerConfig, addr string) error
}
return h
}, cookiesession.Options{
MaxAge: 0, // Scopes it to browser lifecycle, which I think is good for now
Path: "/",
MaxAge: 0, // Scopes it to browser lifecycle, which I think is good for now
Path: "/",
SameSite: http.SameSiteLaxMode,
Insecure: issuer.URL.Hostname() == "localhost", // safari is picky about this
})
if err != nil {
return fmt.Errorf("creating cookie session for webauthn: %w", err)
Expand All @@ -193,21 +196,21 @@ func serve(ctx context.Context, db *DB, issuer issuerConfig, addr string) error

heh := &httpErrHandler{}

// TODO - usernameless via resident keys would be nice, but need to
// see what support is like.
rrk := false
wn, err := webauthn.New(&webauthn.Config{
RPDisplayName: issuer.URL.Hostname(), // Display Name for your site
RPID: issuer.URL.Hostname(), // Generally the FQDN for your site
RPOrigin: issuer.URL.String(), // The origin URL for WebAuthn requests
RPOrigins: []string{
issuer.URL.String(),
},
AuthenticatorSelection: protocol.AuthenticatorSelection{
UserVerification: protocol.VerificationRequired,
RequireResidentKey: &rrk,
RequireResidentKey: ptr(true),
},
})
if err != nil {
return fmt.Errorf("configuring webauthn: %w", err)
}
log.Printf("webaithn: %#v", wn.Config)

// start configuration of webauthn manager
mgr := &webauthnManager{
Expand Down Expand Up @@ -342,3 +345,7 @@ func fatalf(s string, args ...any) {
func logErr(err error) slog.Attr {
return slog.Any("error", err)
}

func ptr[T any](v T) *T {
return &v
}
28 changes: 4 additions & 24 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package main

import (
"embed"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -122,38 +121,19 @@ func (s *oidcServer) AddHandlers(mux *http.ServeMux) {
}

func (s *oidcServer) startLogin(rw http.ResponseWriter, req *http.Request) {
// A lot of this is lifted from the webauthn.BeginLogin message, but doing it
// directly because we aren't hinting the user.

challenge, err := protocol.CreateChallenge()
response, sessionData, err := s.webauthn.BeginDiscoverableLogin(webauthn.WithUserVerification(protocol.VerificationRequired))
if err != nil {
s.httpErr(rw, err)
slog.Error("starting discoverable login", logErr(err))
s.httpErr(rw, errors.New("no active login session"))
return
}

requestOptions := protocol.PublicKeyCredentialRequestOptions{
Challenge: challenge,
Timeout: int(s.webauthn.Config.Timeouts.Login.Timeout),
RelyingPartyID: s.webauthn.Config.RPID,
UserVerification: s.webauthn.Config.AuthenticatorSelection.UserVerification,
// AllowedCredentials: allowedCredentials, // this is what we don't send for resident/usernameless
}

sessionData := webauthn.SessionData{
Challenge: base64.RawURLEncoding.EncodeToString(challenge),
// UserID: user.WebAuthnID(),
AllowedCredentialIDs: requestOptions.GetAllowedCredentialIDs(),
UserVerification: requestOptions.UserVerification,
}

response := protocol.CredentialAssertion{Response: requestOptions}

sess := s.sessmgr.Get(req.Context())
if sess.WebauthnLogin == nil {
s.httpErr(rw, errors.New("no active login session"))
return
}
sess.WebauthnLogin.WebauthnSessionData = &sessionData
sess.WebauthnLogin.WebauthnSessionData = sessionData
s.sessmgr.Save(req.Context(), sess)

if err := json.NewEncoder(rw).Encode(response); err != nil {
Expand Down

0 comments on commit 41fef41

Please sign in to comment.