Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat custom user #1978

Merged
merged 9 commits into from
Dec 5, 2024
Merged

Feat custom user #1978

merged 9 commits into from
Dec 5, 2024

Conversation

FreddyDevelop
Copy link
Contributor

@FreddyDevelop FreddyDevelop commented Nov 20, 2024

Description

Add custom user handle to a webauthn credential. This custom user handle is only used for verifying assertions from imported passkeys.
New passkeys are created with the user id (uuid) from Hanko.

Implementation

Added a new column to the webauthn credentials table. Check in WebauthnService.VerifyAssertionResponse if the userHandle in the response is a uuid, if not treat it as a custom user handle. Get the user based on the credential ID verify the response against the user credentials

Tests

  • Create a passkey for a user with an user which is not a uuid. (E.g. with https://github.com/teamhanko/passkeys)
  • Copy the webauthn credential into the database (currently there is no other way to import a webauthn credential)
  • Add the user handle to the newly created webauthn credential
  • Try to login using this new credential

Keep in mind that the webauthn credential must be created and used with the same RP ID.

Todos

  • Extend the user import to also import a custom user id

Additional context

This is needed when a relying party already has implemented passkeys, but wants to migrate to Hanko and does not use uuids as user identifiers.

Add custom user ID to a user. This custom user ID is only used for verifying assertions from imported passkeys.
backend/dto/admin/user.go Outdated Show resolved Hide resolved
@@ -354,3 +350,39 @@ func (s *webauthnService) VerifyAttestationResponse(p VerifyAttestationResponseP

return credential, nil
}

func (s *webauthnService) GetWebAuthnUser(tx *pop.Connection, credential models.WebauthnCredential, userID uuid.UUID) (webauthn.User, *models.User, error) {
var customUserHandle *string = nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that it is only possible to use (custom) user handles that are not UUID's. I would have expected that UserHandle.Handle is used when assigned to the related credential, the User.ID otherwise, so that the logic would look something like this:

var webAuthnID []bytes

if credentialModel.UserHandle != nil {
  webAuthnID = []byte(credentialModel.UserHandle.Handle)
} else {
  webAuthnID = credentialModel.User.ID.Bytes()
}

backend/persistence/models/user.go Outdated Show resolved Hide resolved
@@ -90,7 +90,7 @@ func NewManager(jwkManager hankoJwk.Manager, config config.Config) (Manager, err
}

// GenerateJWT creates a new session JWT for the given user
func (m *manager) GenerateJWT(userId uuid.UUID, email *dto.EmailJwt) (string, jwt.Token, error) {
func (m *manager) GenerateJWT(userId uuid.UUID, email *dto.EmailJwt, opts ...JWTOptions) (string, jwt.Token, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it make sense to set the email parameter via a JWTOption too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that would make sense. This is just leftover from the previous implementation where a user would have a custom userID. And I forgot that its still there. Maybe we can do it in a separate PR?

@FreddyDevelop FreddyDevelop merged commit 21fd1d4 into main Dec 5, 2024
8 checks passed
@FreddyDevelop FreddyDevelop deleted the feat-custom-user-id branch December 5, 2024 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

2 participants