Search in sources :

Example 1 with AuthenticatorImpl

use of com.webauthn4j.authenticator.AuthenticatorImpl in project keycloak by keycloak.

the class WebAuthnCredentialProvider method isValid.

@Override
public boolean isValid(RealmModel realm, UserModel user, CredentialInput input) {
    if (!WebAuthnCredentialModelInput.class.isInstance(input))
        return false;
    WebAuthnCredentialModelInput context = WebAuthnCredentialModelInput.class.cast(input);
    List<WebAuthnCredentialModelInput> auths = getWebAuthnCredentialModelList(realm, user);
    WebAuthnAuthenticationManager webAuthnAuthenticationManager = new WebAuthnAuthenticationManager();
    AuthenticationData authenticationData = null;
    try {
        for (WebAuthnCredentialModelInput auth : auths) {
            byte[] credentialId = auth.getAttestedCredentialData().getCredentialId();
            if (Arrays.equals(credentialId, context.getAuthenticationRequest().getCredentialId())) {
                Authenticator authenticator = new AuthenticatorImpl(auth.getAttestedCredentialData(), auth.getAttestationStatement(), auth.getCount());
                // parse
                authenticationData = webAuthnAuthenticationManager.parse(context.getAuthenticationRequest());
                // validate
                AuthenticationParameters authenticationParameters = new AuthenticationParameters(context.getAuthenticationParameters().getServerProperty(), authenticator, context.getAuthenticationParameters().isUserVerificationRequired());
                webAuthnAuthenticationManager.validate(authenticationData, authenticationParameters);
                logger.debugv("response.getAuthenticatorData().getFlags() = {0}", authenticationData.getAuthenticatorData().getFlags());
                CredentialModel credModel = getCredentialStore().getStoredCredentialById(realm, user, auth.getCredentialDBId());
                WebAuthnCredentialModel webAuthnCredModel = getCredentialFromModel(credModel);
                // update authenticator counter
                // counters are an optional feature of the spec - if an authenticator does not support them, it
                // will always send zero. MacOS/iOS does this for keys stored in the secure enclave (TouchID/FaceID)
                long count = auth.getCount();
                if (count > 0) {
                    webAuthnCredModel.updateCounter(count + 1);
                    getCredentialStore().updateCredential(realm, user, webAuthnCredModel);
                }
                logger.debugf("Successfully validated WebAuthn credential for user %s", user.getUsername());
                dumpCredentialModel(webAuthnCredModel, auth);
                return true;
            }
        }
    } catch (WebAuthnException wae) {
        wae.printStackTrace();
        throw (wae);
    }
    // no authenticator matched
    return false;
}
Also used : AuthenticationParameters(com.webauthn4j.data.AuthenticationParameters) WebAuthnCredentialModel(org.keycloak.models.credential.WebAuthnCredentialModel) WebAuthnException(com.webauthn4j.util.exception.WebAuthnException) AuthenticationData(com.webauthn4j.data.AuthenticationData) AuthenticatorImpl(com.webauthn4j.authenticator.AuthenticatorImpl) WebAuthnCredentialModel(org.keycloak.models.credential.WebAuthnCredentialModel) WebAuthnAuthenticationManager(com.webauthn4j.WebAuthnAuthenticationManager) Authenticator(com.webauthn4j.authenticator.Authenticator)

Aggregations

WebAuthnAuthenticationManager (com.webauthn4j.WebAuthnAuthenticationManager)1 Authenticator (com.webauthn4j.authenticator.Authenticator)1 AuthenticatorImpl (com.webauthn4j.authenticator.AuthenticatorImpl)1 AuthenticationData (com.webauthn4j.data.AuthenticationData)1 AuthenticationParameters (com.webauthn4j.data.AuthenticationParameters)1 WebAuthnException (com.webauthn4j.util.exception.WebAuthnException)1 WebAuthnCredentialModel (org.keycloak.models.credential.WebAuthnCredentialModel)1