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);
}
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();
}
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();
}
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);
}
}
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;
}
Aggregations