fix: handle multiple webauthn origins (#1078)

* fix(grpc): return CredentialCreationData in webauthn public key

* return id of u2f tokens

* handle separate origins in webauthn

* param
This commit is contained in:
Livio Amstutz
2020-12-08 15:39:58 +01:00
committed by GitHub
parent 12f8c7202c
commit 38478efefb
11 changed files with 75 additions and 50 deletions

View File

@@ -7,25 +7,36 @@ import (
"github.com/duo-labs/webauthn/protocol"
"github.com/duo-labs/webauthn/webauthn"
"github.com/caos/zitadel/internal/config/systemdefaults"
caos_errs "github.com/caos/zitadel/internal/errors"
usr_model "github.com/caos/zitadel/internal/user/model"
)
type WebAuthN struct {
web *webauthn.WebAuthn
webLogin *webauthn.WebAuthn
webConsole *webauthn.WebAuthn
}
func StartServer(displayName, id, origin string) (*WebAuthN, error) {
web, err := webauthn.New(&webauthn.Config{
RPDisplayName: displayName,
RPID: id,
RPOrigin: origin,
func StartServer(sd systemdefaults.WebAuthN) (*WebAuthN, error) {
webLogin, err := webauthn.New(&webauthn.Config{
RPDisplayName: sd.DisplayName,
RPID: sd.ID,
RPOrigin: sd.OriginLogin,
})
if err != nil {
return nil, err
}
webConsole, err := webauthn.New(&webauthn.Config{
RPDisplayName: sd.DisplayName,
RPID: sd.ID,
RPOrigin: sd.OriginConsole,
})
if err != nil {
return nil, err
}
return &WebAuthN{
web: web,
webLogin: webLogin,
webConsole: webConsole,
}, err
}
@@ -54,7 +65,7 @@ func (u *webUser) WebAuthnCredentials() []webauthn.Credential {
return u.credentials
}
func (w *WebAuthN) BeginRegistration(user *usr_model.User, authType usr_model.AuthenticatorAttachment, userVerification usr_model.UserVerificationRequirement, webAuthNs ...*usr_model.WebAuthNToken) (*usr_model.WebAuthNToken, error) {
func (w *WebAuthN) BeginRegistration(user *usr_model.User, authType usr_model.AuthenticatorAttachment, userVerification usr_model.UserVerificationRequirement, isLoginUI bool, webAuthNs ...*usr_model.WebAuthNToken) (*usr_model.WebAuthNToken, error) {
creds := WebAuthNsToCredentials(webAuthNs)
existing := make([]protocol.CredentialDescriptor, len(creds))
for i, cred := range creds {
@@ -63,7 +74,7 @@ func (w *WebAuthN) BeginRegistration(user *usr_model.User, authType usr_model.Au
CredentialID: cred.ID,
}
}
credentialOptions, sessionData, err := w.web.BeginRegistration(
credentialOptions, sessionData, err := w.web(isLoginUI).BeginRegistration(
&webUser{
User: user,
credentials: creds,
@@ -90,7 +101,7 @@ func (w *WebAuthN) BeginRegistration(user *usr_model.User, authType usr_model.Au
}, nil
}
func (w *WebAuthN) FinishRegistration(user *usr_model.User, webAuthN *usr_model.WebAuthNToken, tokenName string, credData []byte) (*usr_model.WebAuthNToken, error) {
func (w *WebAuthN) FinishRegistration(user *usr_model.User, webAuthN *usr_model.WebAuthNToken, tokenName string, credData []byte, isLoginUI bool) (*usr_model.WebAuthNToken, error) {
if webAuthN == nil {
return nil, caos_errs.ThrowInternal(nil, "WEBAU-5M9so", "Errors.User.WebAuthN.NotFound")
}
@@ -99,7 +110,7 @@ func (w *WebAuthN) FinishRegistration(user *usr_model.User, webAuthN *usr_model.
return nil, caos_errs.ThrowInternal(err, "WEBAU-sEr8c", "Errors.User.WebAuthN.ErrorOnParseCredential")
}
sessionData := WebAuthNToSessionData(webAuthN)
credential, err := w.web.CreateCredential(
credential, err := w.web(isLoginUI).CreateCredential(
&webUser{
User: user,
},
@@ -117,8 +128,8 @@ func (w *WebAuthN) FinishRegistration(user *usr_model.User, webAuthN *usr_model.
return webAuthN, nil
}
func (w *WebAuthN) BeginLogin(user *usr_model.User, userVerification usr_model.UserVerificationRequirement, webAuthNs ...*usr_model.WebAuthNToken) (*usr_model.WebAuthNLogin, error) {
assertion, sessionData, err := w.web.BeginLogin(&webUser{
func (w *WebAuthN) BeginLogin(user *usr_model.User, userVerification usr_model.UserVerificationRequirement, isLoginUI bool, webAuthNs ...*usr_model.WebAuthNToken) (*usr_model.WebAuthNLogin, error) {
assertion, sessionData, err := w.web(isLoginUI).BeginLogin(&webUser{
User: user,
credentials: WebAuthNsToCredentials(webAuthNs),
}, webauthn.WithUserVerification(UserVerificationFromModel(userVerification)))
@@ -137,7 +148,7 @@ func (w *WebAuthN) BeginLogin(user *usr_model.User, userVerification usr_model.U
}, nil
}
func (w *WebAuthN) FinishLogin(user *usr_model.User, webAuthN *usr_model.WebAuthNLogin, credData []byte, webAuthNs ...*usr_model.WebAuthNToken) ([]byte, uint32, error) {
func (w *WebAuthN) FinishLogin(user *usr_model.User, webAuthN *usr_model.WebAuthNLogin, credData []byte, isLoginUI bool, webAuthNs ...*usr_model.WebAuthNToken) ([]byte, uint32, error) {
assertionData, err := protocol.ParseCredentialRequestResponseBody(bytes.NewReader(credData))
if err != nil {
return nil, 0, caos_errs.ThrowInternal(err, "WEBAU-ADgv4", "Errors.User.WebAuthN.ValidateLoginFailed")
@@ -146,7 +157,7 @@ func (w *WebAuthN) FinishLogin(user *usr_model.User, webAuthN *usr_model.WebAuth
User: user,
credentials: WebAuthNsToCredentials(webAuthNs),
}
credential, err := w.web.ValidateLogin(webUser, WebAuthNLoginToSessionData(webAuthN), assertionData)
credential, err := w.web(isLoginUI).ValidateLogin(webUser, WebAuthNLoginToSessionData(webAuthN), assertionData)
if err != nil {
return nil, 0, caos_errs.ThrowInternal(err, "WEBAU-3M9si", "Errors.User.WebAuthN.ValidateLoginFailed")
}
@@ -156,3 +167,10 @@ func (w *WebAuthN) FinishLogin(user *usr_model.User, webAuthN *usr_model.WebAuth
}
return credential.ID, credential.Authenticator.SignCount, nil
}
func (w *WebAuthN) web(isLoginUI bool) *webauthn.WebAuthn {
if isLoginUI {
return w.webLogin
}
return w.webConsole
}