KEYCLOAK-12826 WebAuthn fails to login user when their security key supports "user handle"
This commit is contained in:
parent
9e47022116
commit
5db98a58d3
2 changed files with 19 additions and 10 deletions
|
@ -49,6 +49,7 @@ import org.keycloak.models.credential.WebAuthnCredentialModel;
|
|||
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -136,17 +137,16 @@ public class WebAuthnAuthenticator implements Authenticator, CredentialValidator
|
|||
byte[] authenticatorData = Base64Url.decode(params.getFirst(WebAuthnConstants.AUTHENTICATOR_DATA));
|
||||
byte[] signature = Base64Url.decode(params.getFirst(WebAuthnConstants.SIGNATURE));
|
||||
|
||||
String userId = params.getFirst(WebAuthnConstants.USER_HANDLE);
|
||||
boolean isUVFlagChecked = false;
|
||||
String userVerificationRequirement = getWebAuthnPolicy(context).getUserVerificationRequirement();
|
||||
if (WebAuthnConstants.OPTION_REQUIRED.equals(userVerificationRequirement)) isUVFlagChecked = true;
|
||||
|
||||
final String userHandle = params.getFirst(WebAuthnConstants.USER_HANDLE);
|
||||
final String userId;
|
||||
// existing User Handle means that the authenticator used Resident Key supported public key credential
|
||||
if (userId == null || userId.isEmpty()) {
|
||||
if (userHandle == null || userHandle.isEmpty()) {
|
||||
// Resident Key not supported public key credential was used
|
||||
// so rely on the user that has already been authenticated
|
||||
userId = context.getUser().getId();
|
||||
} else {
|
||||
// decode using the same charset as it has been encoded (see: WebAuthnRegister.java)
|
||||
userId = new String(Base64Url.decode(userHandle), StandardCharsets.UTF_8);
|
||||
if (context.getUser() != null) {
|
||||
// Resident Key supported public key credential was used,
|
||||
// so need to confirm whether the already authenticated user is equals to one authenticated by the webauthn authenticator
|
||||
|
@ -165,6 +165,11 @@ public class WebAuthnAuthenticator implements Authenticator, CredentialValidator
|
|||
// NOP
|
||||
}
|
||||
}
|
||||
|
||||
boolean isUVFlagChecked = false;
|
||||
String userVerificationRequirement = getWebAuthnPolicy(context).getUserVerificationRequirement();
|
||||
if (WebAuthnConstants.OPTION_REQUIRED.equals(userVerificationRequirement)) isUVFlagChecked = true;
|
||||
|
||||
UserModel user = session.users().getUserById(userId, context.getRealm());
|
||||
WebAuthnAuthenticationContext authenticationContext = new WebAuthnAuthenticationContext(
|
||||
credentialId,
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.keycloak.authentication.requiredactions;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
@ -94,7 +95,10 @@ public class WebAuthnRegister implements RequiredActionProvider, CredentialRegis
|
|||
@Override
|
||||
public void requiredActionChallenge(RequiredActionContext context) {
|
||||
UserModel userModel = context.getUser();
|
||||
String userid = Base64Url.encode(userModel.getId().getBytes());
|
||||
// Use standard UTF-8 charset to get bytes from string.
|
||||
// Otherwise the platform's default charset is used and it might cause problems later when
|
||||
// decoded on different system.
|
||||
String userId = Base64Url.encode(userModel.getId().getBytes(StandardCharsets.UTF_8));
|
||||
String username = userModel.getUsername();
|
||||
Challenge challenge = new DefaultChallenge();
|
||||
String challengeValue = Base64Url.encode(challenge.getValue());
|
||||
|
@ -133,7 +137,7 @@ public class WebAuthnRegister implements RequiredActionProvider, CredentialRegis
|
|||
|
||||
Response form = context.form()
|
||||
.setAttribute(WebAuthnConstants.CHALLENGE, challengeValue)
|
||||
.setAttribute(WebAuthnConstants.USER_ID, userid)
|
||||
.setAttribute(WebAuthnConstants.USER_ID, userId)
|
||||
.setAttribute(WebAuthnConstants.USER_NAME, username)
|
||||
.setAttribute(WebAuthnConstants.RP_ENTITY_NAME, rpEntityName)
|
||||
.setAttribute(WebAuthnConstants.SIGNATURE_ALGORITHMS, signatureAlgorithms)
|
||||
|
|
Loading…
Reference in a new issue