Search in sources :

Example 1 with UserCredentialModel

use of org.keycloak.models.UserCredentialModel in project keycloak by keycloak.

the class CredentialHelper method createOTPCredential.

/**
 * Create OTP credential either in userStorage or local storage (Keycloak DB)
 *
 * @return true if credential was successfully created either in the user storage or Keycloak DB. False if error happened (EG. during HOTP validation)
 */
public static boolean createOTPCredential(KeycloakSession session, RealmModel realm, UserModel user, String totpCode, OTPCredentialModel credentialModel) {
    CredentialProvider otpCredentialProvider = session.getProvider(CredentialProvider.class, "keycloak-otp");
    String totpSecret = credentialModel.getOTPSecretData().getValue();
    UserCredentialModel otpUserCredential = new UserCredentialModel("", realm.getOTPPolicy().getType(), totpSecret);
    boolean userStorageCreated = session.userCredentialManager().updateCredential(realm, user, otpUserCredential);
    String credentialId = null;
    if (userStorageCreated) {
        logger.debugf("Created OTP credential for user '%s' in the user storage", user.getUsername());
    } else {
        CredentialModel createdCredential = otpCredentialProvider.createCredential(realm, user, credentialModel);
        credentialId = createdCredential.getId();
    }
    // If the type is HOTP, call verify once to consume the OTP used for registration and increase the counter.
    UserCredentialModel credential = new UserCredentialModel(credentialId, otpCredentialProvider.getType(), totpCode);
    return session.userCredentialManager().isValid(realm, user, credential);
}
Also used : UserCredentialModel(org.keycloak.models.UserCredentialModel) CredentialModel(org.keycloak.credential.CredentialModel) OTPCredentialModel(org.keycloak.models.credential.OTPCredentialModel) CredentialProvider(org.keycloak.credential.CredentialProvider) UserCredentialModel(org.keycloak.models.UserCredentialModel)

Example 2 with UserCredentialModel

use of org.keycloak.models.UserCredentialModel in project keycloak by keycloak.

the class OTPFormAuthenticator method validateOTP.

public void validateOTP(AuthenticationFlowContext context) {
    MultivaluedMap<String, String> inputData = context.getHttpRequest().getDecodedFormParameters();
    String otp = inputData.getFirst("otp");
    String credentialId = inputData.getFirst("selectedCredentialId");
    if (credentialId == null || credentialId.isEmpty()) {
        OTPCredentialModel defaultOtpCredential = getCredentialProvider(context.getSession()).getDefaultCredential(context.getSession(), context.getRealm(), context.getUser());
        credentialId = defaultOtpCredential == null ? "" : defaultOtpCredential.getId();
    }
    context.getEvent().detail(Details.SELECTED_CREDENTIAL_ID, credentialId);
    context.form().setAttribute(SELECTED_OTP_CREDENTIAL_ID, credentialId);
    UserModel userModel = context.getUser();
    if (!enabledUser(context, userModel)) {
        // error in context is set in enabledUser/isDisabledByBruteForce
        return;
    }
    if (otp == null) {
        Response challengeResponse = challenge(context, null);
        context.challenge(challengeResponse);
        return;
    }
    boolean valid = context.getSession().userCredentialManager().isValid(context.getRealm(), context.getUser(), new UserCredentialModel(credentialId, getCredentialProvider(context.getSession()).getType(), otp));
    if (!valid) {
        context.getEvent().user(userModel).error(Errors.INVALID_USER_CREDENTIALS);
        Response challengeResponse = challenge(context, Messages.INVALID_TOTP, Validation.FIELD_OTP_CODE);
        context.failureChallenge(AuthenticationFlowError.INVALID_CREDENTIALS, challengeResponse);
        return;
    }
    context.success();
}
Also used : UserModel(org.keycloak.models.UserModel) Response(javax.ws.rs.core.Response) OTPCredentialModel(org.keycloak.models.credential.OTPCredentialModel) UserCredentialModel(org.keycloak.models.UserCredentialModel)

Example 3 with UserCredentialModel

use of org.keycloak.models.UserCredentialModel in project keycloak by keycloak.

the class ValidateOTP method authenticate.

@Override
public void authenticate(AuthenticationFlowContext context) {
    if (!configuredFor(context.getSession(), context.getRealm(), context.getUser())) {
        if (context.getExecution().isConditional()) {
            context.attempted();
        } else if (context.getExecution().isRequired()) {
            context.getEvent().error(Errors.INVALID_USER_CREDENTIALS);
            Response challengeResponse = errorResponse(Response.Status.UNAUTHORIZED.getStatusCode(), "invalid_grant", "Invalid user credentials");
            context.failure(AuthenticationFlowError.INVALID_USER, challengeResponse);
        }
        return;
    }
    MultivaluedMap<String, String> inputData = context.getHttpRequest().getDecodedFormParameters();
    String otp = inputData.getFirst("otp");
    // KEYCLOAK-12908 Backwards compatibility. If paramter "otp" is null, then assign "totp".
    otp = (otp == null) ? inputData.getFirst("totp") : otp;
    // Always use default OTP credential in case of direct grant authentication
    String credentialId = getCredentialProvider(context.getSession()).getDefaultCredential(context.getSession(), context.getRealm(), context.getUser()).getId();
    if (otp == null) {
        if (context.getUser() != null) {
            context.getEvent().user(context.getUser());
        }
        context.getEvent().error(Errors.INVALID_USER_CREDENTIALS);
        Response challengeResponse = errorResponse(Response.Status.UNAUTHORIZED.getStatusCode(), "invalid_grant", "Invalid user credentials");
        context.failure(AuthenticationFlowError.INVALID_USER, challengeResponse);
        return;
    }
    boolean valid = getCredentialProvider(context.getSession()).isValid(context.getRealm(), context.getUser(), new UserCredentialModel(credentialId, OTPCredentialModel.TYPE, otp));
    if (!valid) {
        context.getEvent().user(context.getUser());
        context.getEvent().error(Errors.INVALID_USER_CREDENTIALS);
        Response challengeResponse = errorResponse(Response.Status.UNAUTHORIZED.getStatusCode(), "invalid_grant", "Invalid user credentials");
        context.failure(AuthenticationFlowError.INVALID_USER, challengeResponse);
        return;
    }
    context.success();
}
Also used : Response(javax.ws.rs.core.Response) UserCredentialModel(org.keycloak.models.UserCredentialModel)

Example 4 with UserCredentialModel

use of org.keycloak.models.UserCredentialModel in project keycloak by keycloak.

the class SpnegoAuthenticator method authenticate.

@Override
public void authenticate(AuthenticationFlowContext context) {
    HttpRequest request = context.getHttpRequest();
    String authHeader = request.getHttpHeaders().getRequestHeaders().getFirst(HttpHeaders.AUTHORIZATION);
    if (authHeader == null) {
        Response challenge = challengeNegotiation(context, null);
        context.forceChallenge(challenge);
        return;
    }
    String[] tokens = authHeader.split(" ");
    if (tokens.length == 0) {
        // assume not supported
        logger.debug("Invalid length of tokens: " + tokens.length);
        context.attempted();
        return;
    }
    if (!KerberosConstants.NEGOTIATE.equalsIgnoreCase(tokens[0])) {
        logger.debug("Unknown scheme " + tokens[0]);
        context.attempted();
        return;
    }
    if (tokens.length != 2) {
        context.failure(AuthenticationFlowError.INVALID_CREDENTIALS);
        return;
    }
    String spnegoToken = tokens[1];
    UserCredentialModel spnegoCredential = UserCredentialModel.kerberos(spnegoToken);
    CredentialValidationOutput output = context.getSession().userCredentialManager().authenticate(context.getSession(), context.getRealm(), spnegoCredential);
    if (output == null) {
        logger.warn("Received kerberos token, but there is no user storage provider that handles kerberos credentials.");
        context.attempted();
        return;
    }
    if (output.getAuthStatus() == CredentialValidationOutput.Status.AUTHENTICATED) {
        context.setUser(output.getAuthenticatedUser());
        if (output.getState() != null && !output.getState().isEmpty()) {
            for (Map.Entry<String, String> entry : output.getState().entrySet()) {
                context.getAuthenticationSession().setUserSessionNote(entry.getKey(), entry.getValue());
            }
        }
        context.success();
    } else if (output.getAuthStatus() == CredentialValidationOutput.Status.CONTINUE) {
        String spnegoResponseToken = (String) output.getState().get(KerberosConstants.RESPONSE_TOKEN);
        Response challenge = challengeNegotiation(context, spnegoResponseToken);
        context.challenge(challenge);
    } else {
        context.getEvent().error(Errors.INVALID_USER_CREDENTIALS);
        context.failure(AuthenticationFlowError.INVALID_CREDENTIALS);
    }
}
Also used : HttpRequest(org.jboss.resteasy.spi.HttpRequest) Response(javax.ws.rs.core.Response) CredentialValidationOutput(org.keycloak.models.CredentialValidationOutput) UserCredentialModel(org.keycloak.models.UserCredentialModel) Map(java.util.Map)

Example 5 with UserCredentialModel

use of org.keycloak.models.UserCredentialModel in project keycloak by keycloak.

the class BasicAuthOTPAuthenticator method checkOtp.

private boolean checkOtp(AuthenticationFlowContext context, String otp) {
    OTPCredentialModel preferredCredential = getCredentialProvider(context.getSession()).getDefaultCredential(context.getSession(), context.getRealm(), context.getUser());
    boolean valid = getCredentialProvider(context.getSession()).isValid(context.getRealm(), context.getUser(), new UserCredentialModel(preferredCredential.getId(), getCredentialProvider(context.getSession()).getType(), otp));
    if (!valid) {
        context.getEvent().user(context.getUser()).error(Errors.INVALID_USER_CREDENTIALS);
        if (context.getExecution().isRequired()) {
            Response challengeResponse = challenge(context, Messages.INVALID_TOTP, Validation.FIELD_OTP_CODE);
            context.failureChallenge(AuthenticationFlowError.INVALID_CREDENTIALS, challengeResponse);
        } else {
            context.attempted();
        }
        return false;
    }
    return true;
}
Also used : Response(javax.ws.rs.core.Response) OTPCredentialModel(org.keycloak.models.credential.OTPCredentialModel) UserCredentialModel(org.keycloak.models.UserCredentialModel)

Aggregations

UserCredentialModel (org.keycloak.models.UserCredentialModel)20 UserModel (org.keycloak.models.UserModel)8 CredentialModel (org.keycloak.credential.CredentialModel)5 Response (javax.ws.rs.core.Response)4 OTPCredentialModel (org.keycloak.models.credential.OTPCredentialModel)4 PasswordHashProvider (org.keycloak.credential.hash.PasswordHashProvider)3 CredentialValidationOutput (org.keycloak.models.CredentialValidationOutput)3 PasswordPolicy (org.keycloak.models.PasswordPolicy)3 RealmModel (org.keycloak.models.RealmModel)3 CachedUserModel (org.keycloak.models.cache.CachedUserModel)3 HashMap (java.util.HashMap)2 NotFoundException (javax.ws.rs.NotFoundException)2 Path (javax.ws.rs.Path)2 Test (org.junit.Test)2 SPNEGOAuthenticator (org.keycloak.federation.kerberos.impl.SPNEGOAuthenticator)2 OTPPolicy (org.keycloak.models.OTPPolicy)2 UserCache (org.keycloak.models.cache.UserCache)2 PasswordCredentialModel (org.keycloak.models.credential.PasswordCredentialModel)2 PasswordUserCredentialModel (org.keycloak.models.credential.PasswordUserCredentialModel)2 TimeBasedOTP (org.keycloak.models.utils.TimeBasedOTP)2