mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 18:17:35 +00:00
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:
@@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user