Skip to content

Commit

Permalink
fix: use correct names in WebAuthN dialogs (ory#3215)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonas-jonas authored Apr 6, 2023
1 parent 17f0de4 commit 3bc1ff0
Show file tree
Hide file tree
Showing 10 changed files with 235 additions and 66 deletions.
6 changes: 2 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cover.out
.idea/
tmp/
.DS_Store
./kratos
/kratos
packrd/
*-packr.go
dist/
Expand Down Expand Up @@ -60,7 +60,5 @@ test/e2e/hydra-kratos-login-consent/hydra-kratos-login-consent
test/e2e/proxy.json
test/e2e/kratos.*.yml

# Kratos executable
kratos
# VSCode debug artifact
__debug_bin
__debug_bin
50 changes: 50 additions & 0 deletions contrib/quickstart/kratos/webauthn/identity.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"$id": "https://schemas.ory.sh/presets/kratos/quickstart/email-password/identity.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Person",
"type": "object",
"properties": {
"traits": {
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email",
"title": "E-Mail",
"minLength": 3,
"ory.sh/kratos": {
"credentials": {
"password": {
"identifier": true
},
"webauthn": {
"identifier": true
}
},
"verification": {
"via": "email"
},
"recovery": {
"via": "email"
}
}
},
"name": {
"type": "object",
"properties": {
"first": {
"title": "First Name",
"type": "string"
},
"last": {
"title": "Last Name",
"type": "string"
}
}
}
},
"required": ["email"],
"additionalProperties": false
}
}
}
107 changes: 107 additions & 0 deletions contrib/quickstart/kratos/webauthn/kratos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
version: v0.11.0

dsn: memory

serve:
public:
base_url: http://localhost:4433/
cors:
enabled: true
admin:
base_url: http://kratos:4434/

selfservice:
default_browser_return_url: http://localhost:4455/
allowed_return_urls:
- http://localhost:4455

methods:
password:
enabled: false
totp:
config:
issuer: Kratos
enabled: true
lookup_secret:
enabled: true
link:
enabled: true
code:
enabled: true
webauthn:
config:
passwordless: true
rp:
display_name: Your Application name
# Set 'id' to the top-level domain.
id: localhost
# Set 'origin' to the exact URL of the page that prompts the user to use WebAuthn. You must include the scheme, host, and port.
origin: http://localhost:4455
enabled: true

flows:
error:
ui_url: http://localhost:4455/error

settings:
ui_url: http://localhost:4455/settings
privileged_session_max_age: 15m
required_aal: highest_available

recovery:
enabled: true
ui_url: http://localhost:4455/recovery
use: code

verification:
enabled: true
ui_url: http://localhost:4455/verification
use: code
after:
default_browser_return_url: http://localhost:4455/

logout:
after:
default_browser_return_url: http://localhost:4455/login

login:
ui_url: http://localhost:4455/login
lifespan: 10m

registration:
lifespan: 10m
ui_url: http://localhost:4455/registration
after:
password:
hooks:
- hook: session
- hook: show_verification_ui

log:
level: debug
format: text
leak_sensitive_values: true

secrets:
cookie:
- PLEASE-CHANGE-ME-I-AM-VERY-INSECURE
cipher:
- 32-LONG-SECRET-NOT-SECURE-AT-ALL

ciphers:
algorithm: xchacha20-poly1305

hashers:
algorithm: bcrypt
bcrypt:
cost: 8

identity:
default_schema_id: default
schemas:
- id: default
url: file:///etc/config/kratos/identity.schema.json

courier:
smtp:
connection_uri: smtps://test:test@mailslurper:1025/?skip_ssl_verify=true
18 changes: 18 additions & 0 deletions quickstart-webauthn.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: "3.7"

services:
kratos-migrate:
volumes:
- type: bind
source: ./contrib/quickstart/kratos/webauthn
target: /etc/config/kratos

kratos:
volumes:
- type: bind
source: ./contrib/quickstart/kratos/webauthn
target: /etc/config/kratos

kratos-selfservice-ui-node:
environment:
- KRATOS_BROWSER_URL=http://localhost:4433/
10 changes: 5 additions & 5 deletions selfservice/strategy/webauthn/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,16 @@ func (s *Strategy) populateLoginMethod(r *http.Request, sr *login.Flow, i *ident
}

if len(webAuthCreds) == 0 {
// Identity has no webauth
// Identity has no webauthn
return ErrNoCredentials
}

web, err := s.newWebAuthn(r.Context())
web, err := webauthn.New(s.d.Config().WebAuthnConfig(r.Context()))
if err != nil {
return errors.WithStack(herodot.ErrInternalServerError.WithReasonf("Unable to initiate WebAuth.").WithDebug(err.Error()))
}

options, sessionData, err := web.BeginLogin(&wrappedUser{id: conf.UserHandle, c: webAuthCreds})
options, sessionData, err := web.BeginLogin(NewUser(conf.UserHandle, webAuthCreds, web.Config))
if err != nil {
return errors.WithStack(herodot.ErrInternalServerError.WithReasonf("Unable to initiate WebAuth login.").WithDebug(err.Error()))
}
Expand Down Expand Up @@ -295,7 +295,7 @@ func (s *Strategy) loginAuthenticate(_ http.ResponseWriter, r *http.Request, f *
return nil, s.handleLoginError(r, f, errors.WithStack(herodot.ErrInternalServerError.WithReason("The WebAuthn credentials could not be decoded properly").WithDebug(err.Error()).WithWrap(err)))
}

web, err := s.newWebAuthn(r.Context())
web, err := webauthn.New(s.d.Config().WebAuthnConfig(r.Context()))
if err != nil {
return nil, s.handleLoginError(r, f, errors.WithStack(herodot.ErrInternalServerError.WithReasonf("Unable to get webAuthn config.").WithDebug(err.Error())))
}
Expand All @@ -315,7 +315,7 @@ func (s *Strategy) loginAuthenticate(_ http.ResponseWriter, r *http.Request, f *
webAuthCreds = o.Credentials.ToWebAuthn()
}

if _, err := web.ValidateLogin(&wrappedUser{id: o.UserHandle, c: webAuthCreds}, webAuthnSess, webAuthnResponse); err != nil {
if _, err := web.ValidateLogin(NewUser(o.UserHandle, webAuthCreds, web.Config), webAuthnSess, webAuthnResponse); err != nil {
return nil, s.handleLoginError(r, f, errors.WithStack(schema.NewWebAuthnVerifierWrongError("#/")))
}

Expand Down
35 changes: 0 additions & 35 deletions selfservice/strategy/webauthn/mock.go

This file was deleted.

11 changes: 6 additions & 5 deletions selfservice/strategy/webauthn/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,12 @@ func (s *Strategy) Register(w http.ResponseWriter, r *http.Request, f *registrat
return s.handleRegistrationError(w, r, f, &p, errors.WithStack(herodot.ErrBadRequest.WithReasonf("Unable to parse WebAuthn response: %s", err)))
}

web, err := s.newWebAuthn(r.Context())
web, err := webauthn.New(s.d.Config().WebAuthnConfig(r.Context()))
if err != nil {
return s.handleRegistrationError(w, r, f, &p, errors.WithStack(herodot.ErrInternalServerError.WithReasonf("Unable to get webAuthn config.").WithDebug(err.Error())))
}

credential, err := web.CreateCredential(&wrappedUser{id: webAuthnSess.UserID}, webAuthnSess, webAuthnResponse)
credential, err := web.CreateCredential(NewUser(webAuthnSess.UserID, nil, web.Config), webAuthnSess, webAuthnResponse)
if err != nil {
return s.handleRegistrationError(w, r, f, &p, errors.WithStack(herodot.ErrInternalServerError.WithReasonf("Unable to create WebAuthn credential: %s", err)))
}
Expand Down Expand Up @@ -197,13 +197,14 @@ func (s *Strategy) PopulateRegistrationMethod(r *http.Request, f *registration.F
f.UI.SetNode(n)
}

web, err := s.newWebAuthn(r.Context())
web, err := webauthn.New(s.d.Config().WebAuthnConfig(r.Context()))
if err != nil {
return err
return errors.WithStack(err)
}

webauthID := x.NewUUID()
option, sessionData, err := web.BeginRegistration(&wrappedUser{id: webauthID[:]})
user := NewUser(webauthID[:], nil, s.d.Config().WebAuthnConfig(r.Context()))
option, sessionData, err := web.BeginRegistration(user)
if err != nil {
return errors.WithStack(err)
}
Expand Down
10 changes: 5 additions & 5 deletions selfservice/strategy/webauthn/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,12 @@ func (s *Strategy) continueSettingsFlowAdd(w http.ResponseWriter, r *http.Reques
return errors.WithStack(herodot.ErrBadRequest.WithReasonf("Unable to parse WebAuthn response: %s", err))
}

web, err := s.newWebAuthn(r.Context())
web, err := webauthn.New(s.d.Config().WebAuthnConfig(r.Context()))
if err != nil {
return errors.WithStack(herodot.ErrInternalServerError.WithReasonf("Unable to get webAuthn config.").WithDebug(err.Error()))
}

credential, err := web.CreateCredential(&wrappedUser{id: ctxUpdate.Session.IdentityID[:]}, webAuthnSess, webAuthnResponse)
credential, err := web.CreateCredential(NewUser(ctxUpdate.Session.IdentityID[:], nil, web.Config), webAuthnSess, webAuthnResponse)
if err != nil {
return errors.WithStack(herodot.ErrInternalServerError.WithReasonf("Unable to create WebAuthn credential: %s", err))
}
Expand Down Expand Up @@ -356,12 +356,12 @@ func (s *Strategy) PopulateSettingsMethod(r *http.Request, id *identity.Identity
}
}

web, err := s.newWebAuthn(r.Context())
web, err := webauthn.New(s.d.Config().WebAuthnConfig(r.Context()))
if err != nil {
return err
return errors.WithStack(err)
}

option, sessionData, err := web.BeginRegistration(&wrappedUser{id: id.ID[:]})
option, sessionData, err := web.BeginRegistration(NewUser(id.ID[:], nil, web.Config))
if err != nil {
return errors.WithStack(err)
}
Expand Down
12 changes: 0 additions & 12 deletions selfservice/strategy/webauthn/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import (
"context"
"encoding/json"

"github.com/duo-labs/webauthn/webauthn"

"github.com/pkg/errors"

"github.com/ory/kratos/continuity"
Expand Down Expand Up @@ -114,16 +112,6 @@ func (s *Strategy) NodeGroup() node.UiNodeGroup {
return node.WebAuthnGroup
}

func (s *Strategy) newWebAuthn(ctx context.Context) (*webauthn.WebAuthn, error) {
c := s.d.Config()
web, err := webauthn.New(c.WebAuthnConfig(ctx))
if err != nil {
return nil, errors.WithStack(err)
}

return web, nil
}

func (s *Strategy) CompletedAuthenticationMethod(ctx context.Context) session.AuthenticationMethod {
aal := identity.AuthenticatorAssuranceLevel1
if !s.d.Config().WebAuthnForPasswordless(ctx) {
Expand Down
Loading

0 comments on commit 3bc1ff0

Please sign in to comment.