private CredentialEntity setCredentials(UserEntity user, UserCredentialModel cred) { CredentialEntity credentialEntity = new CredentialEntity(); credentialEntity.setId(KeycloakModelUtils.generateId()); credentialEntity.setType(cred.getType()); credentialEntity.setDevice(cred.getDevice()); credentialEntity.setUser(user); return credentialEntity; }
@Override public boolean validCredentials( RealmModel realm, UserModel user, List<UserCredentialModel> input) { for (UserCredentialModel cred : input) { if (cred.getType().equals(UserCredentialModel.PASSWORD)) { return validPassword(realm, user, cred.getValue()); } else { return false; // invalid cred type } } return true; }
public static UserModel addLocalUser( KeycloakSession session, RealmModel realm, String username, String email, String password) { UserModel user = session.userStorage().addUser(realm, username); user.setEmail(email); user.setEnabled(true); UserCredentialModel creds = new UserCredentialModel(); creds.setType(CredentialRepresentation.PASSWORD); creds.setValue(password); session.userCredentialManager().updateCredential(realm, user, creds); return user; }
@Override public void config( RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { UserModel user = manager.getSession().users().addUser(appRealm, "login-test"); user.setEmail("*****@*****.**"); user.setEnabled(true); userId = user.getId(); UserCredentialModel creds = new UserCredentialModel(); creds.setType(CredentialRepresentation.PASSWORD); creds.setValue("password"); user.updateCredential(creds); appRealm.setEventsListeners(Collections.singleton("dummy")); }
@Override public CredentialValidationOutput validCredentials( RealmModel realm, UserCredentialModel credential) { if (credential.getType().equals(UserCredentialModel.KERBEROS)) { if (kerberosConfig.isAllowKerberosAuthentication()) { String spnegoToken = credential.getValue(); SPNEGOAuthenticator spnegoAuthenticator = factory.createSPNEGOAuthenticator(spnegoToken, kerberosConfig); spnegoAuthenticator.authenticate(); Map<String, String> state = new HashMap<String, String>(); if (spnegoAuthenticator.isAuthenticated()) { // TODO: This assumes that LDAP "uid" is equal to kerberos principal name. Like uid // "hnelson" and kerberos principal "*****@*****.**". // Check if it's correct or if LDAP attribute for mapping kerberos principal should be // available (For ApacheDS it seems to be attribute "krb5PrincipalName" but on MSAD it's // likely different) String username = spnegoAuthenticator.getAuthenticatedUsername(); UserModel user = findOrCreateAuthenticatedUser(realm, username); if (user == null) { logger.warnf( "Kerberos/SPNEGO authentication succeeded with username [%s], but couldn't find or create user with federation provider [%s]", username, model.getDisplayName()); return CredentialValidationOutput.failed(); } else { String delegationCredential = spnegoAuthenticator.getSerializedDelegationCredential(); if (delegationCredential != null) { state.put(KerberosConstants.GSS_DELEGATION_CREDENTIAL, delegationCredential); } return new CredentialValidationOutput( user, CredentialValidationOutput.Status.AUTHENTICATED, state); } } else { state.put(KerberosConstants.RESPONSE_TOKEN, spnegoAuthenticator.getResponseToken()); return new CredentialValidationOutput( null, CredentialValidationOutput.Status.CONTINUE, state); } } } return CredentialValidationOutput.failed(); }
private void setValue(CredentialEntity credentialEntity, UserCredentialModel cred) { UserCredentialValueModel encoded = PasswordHashManager.encode(session, realm, cred.getValue()); credentialEntity.setCreatedDate(Time.toMillis(Time.currentTime())); credentialEntity.setAlgorithm(encoded.getAlgorithm()); credentialEntity.setValue(encoded.getValue()); credentialEntity.setSalt(encoded.getSalt()); credentialEntity.setHashIterations(encoded.getHashIterations()); }
@Override public void updateCredential(UserCredentialModel cred) { if (cred.getType().equals(UserCredentialModel.PASSWORD)) { updatePasswordCredential(cred); } else { CredentialEntity credentialEntity = getCredentialEntity(user, cred.getType()); if (credentialEntity == null) { credentialEntity = setCredentials(user, cred); credentialEntity.setValue(cred.getValue()); user.getCredentials().add(credentialEntity); } else { credentialEntity.setValue(cred.getValue()); } } }
@Override public void updateCredential(UserCredentialModel cred) { if (!provider.getSupportedCredentialTypes(delegate).contains(cred.getType())) { delegate.updateCredential(cred); return; } if (cred.getType().equals(UserCredentialModel.PASSWORD)) { LDAPIdentityStore ldapIdentityStore = provider.getLdapIdentityStore(); String password = cred.getValue(); ldapIdentityStore.updatePassword(ldapObject, password); } else { logger.warnf( "Don't know how to update credential of type [%s] for user [%s]", cred.getType(), delegate.getUsername()); } }
@Override public void updateCredential(UserCredentialModel cred) { CredentialEntity credentialEntity = getCredentialEntity(user, cred.getType()); if (credentialEntity == null) { credentialEntity = new CredentialEntity(); credentialEntity.setId(KeycloakModelUtils.generateId()); credentialEntity.setType(cred.getType()); credentialEntity.setDevice(cred.getDevice()); credentialEntity.setUser(user); em.persist(credentialEntity); user.getCredentials().add(credentialEntity); } if (cred.getType().equals(UserCredentialModel.PASSWORD)) { byte[] salt = getSalt(); int hashIterations = 1; PasswordPolicy policy = realm.getPasswordPolicy(); if (policy != null) { hashIterations = policy.getHashIterations(); if (hashIterations == -1) hashIterations = 1; } credentialEntity.setValue( new Pbkdf2PasswordEncoder(salt).encode(cred.getValue(), hashIterations)); credentialEntity.setSalt(salt); credentialEntity.setHashIterations(hashIterations); } else { credentialEntity.setValue(cred.getValue()); } credentialEntity.setDevice(cred.getDevice()); em.flush(); }
@Override public void config( RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { UserModel user = appRealm.getUser("test-user@localhost"); ApplicationModel accountApp = appRealm .getApplicationNameMap() .get(org.keycloak.models.Constants.ACCOUNT_APPLICATION); for (String r : accountApp.getDefaultRoles()) { accountApp.grantRole(user, accountApp.getRole(r)); } UserModel user2 = appRealm.addUser("test-user-no-access@localhost"); user2.setEnabled(true); UserCredentialModel creds = new UserCredentialModel(); creds.setType(CredentialRepresentation.PASSWORD); creds.setValue("password"); appRealm.updateCredential(user2, creds); }
@Override public void updateCredential(UserCredentialModel cred) { if (!provider.getSupportedCredentialTypes(delegate).contains(cred.getType())) { delegate.updateCredential(cred); return; } IdentityManager identityManager = provider.getIdentityManager(); try { User picketlinkUser = BasicModel.getUser(identityManager, getUsername()); if (picketlinkUser == null) { logger.debugf("User '%s' doesn't exists. Skip password update", getUsername()); throw new IllegalStateException("User doesn't exist in LDAP storage"); } if (cred.getType().equals(UserCredentialModel.PASSWORD)) { identityManager.updateCredential( picketlinkUser, new Password(cred.getValue().toCharArray())); } else if (cred.getType().equals(UserCredentialModel.TOTP)) { TOTPCredential credential = new TOTPCredential(cred.getValue()); credential.setDevice(cred.getDevice()); identityManager.updateCredential(picketlinkUser, credential); } } catch (IdentityManagementException ie) { throw new ModelException(ie); } }
@Override public void authenticate(AuthenticationFlowContext context) { if (!isConfigured(context.getSession(), context.getRealm(), context.getUser())) { if (context.getExecution().isOptional()) { 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; } String otp = retrieveOTP(context); 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 = context .getSession() .userCredentialManager() .isValid( context.getRealm(), context.getUser(), UserCredentialModel.otp(context.getRealm().getOTPPolicy().getType(), 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(); }
private void updateOtpCredential(UserCredentialModel cred) { CredentialEntity credentialEntity = getCredentialEntity(user, cred.getType()); if (credentialEntity == null) { credentialEntity = setCredentials(user, cred); credentialEntity.setValue(cred.getValue()); OTPPolicy otpPolicy = realm.getOTPPolicy(); credentialEntity.setAlgorithm(otpPolicy.getAlgorithm()); credentialEntity.setDigits(otpPolicy.getDigits()); credentialEntity.setCounter(otpPolicy.getInitialCounter()); credentialEntity.setPeriod(otpPolicy.getPeriod()); em.persist(credentialEntity); user.getCredentials().add(credentialEntity); } else { OTPPolicy policy = realm.getOTPPolicy(); credentialEntity.setDigits(policy.getDigits()); credentialEntity.setCounter(policy.getInitialCounter()); credentialEntity.setAlgorithm(policy.getAlgorithm()); credentialEntity.setValue(cred.getValue()); credentialEntity.setPeriod(policy.getPeriod()); } }
private void setValue(CredentialEntity credentialEntity, UserCredentialModel cred) { byte[] salt = getSalt(); int hashIterations = 1; PasswordPolicy policy = realm.getPasswordPolicy(); if (policy != null) { hashIterations = policy.getHashIterations(); if (hashIterations == -1) hashIterations = 1; } credentialEntity.setCreatedDate(Time.toMillis(Time.currentTime())); credentialEntity.setValue( new Pbkdf2PasswordEncoder(salt).encode(cred.getValue(), hashIterations)); credentialEntity.setSalt(salt); credentialEntity.setHashIterations(hashIterations); }
@Override public void config( RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm); ClientModel accountApp = appRealm .getClientNameMap() .get(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_CLIENT_ID); UserModel user2 = manager.getSession().users().addUser(appRealm, "test-user-no-access@localhost"); user2.setEnabled(true); user2.setEmail("test-user-no-access@localhost"); for (String r : accountApp.getDefaultRoles()) { user2.deleteRoleMapping(accountApp.getRole(r)); } UserCredentialModel creds = new UserCredentialModel(); creds.setType(CredentialRepresentation.PASSWORD); creds.setValue("password"); user2.updateCredential(creds); }
@Override public void config( RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { ClientModel app = appRealm.addClient("resource-owner"); app.setSecret("secret"); UserModel user = session.users().addUser(appRealm, "direct-login"); user.setEmail("direct-login@localhost"); user.setEnabled(true); userId = user.getId(); session .users() .updateCredential(appRealm, user, UserCredentialModel.password("password")); }
/** * Get the client secret * * @return */ @Path("client-secret") @GET @NoCache @Produces(MediaType.APPLICATION_JSON) public CredentialRepresentation getClientSecret() { auth.requireView(); if (client == null) { throw new NotFoundException("Could not find client"); } logger.debug("getClientSecret"); UserCredentialModel model = UserCredentialModel.secret(client.getSecret()); if (model == null) throw new NotFoundException("Client does not have a secret"); return ModelToRepresentation.toRepresentation(model); }
private void updatePasswordCredential(UserCredentialModel cred) { CredentialEntity credentialEntity = getCredentialEntity(user, cred.getType()); if (credentialEntity == null) { credentialEntity = setCredentials(user, cred); setValue(credentialEntity, cred); em.persist(credentialEntity); user.getCredentials().add(credentialEntity); } else { int expiredPasswordsPolicyValue = -1; PasswordPolicy policy = realm.getPasswordPolicy(); if (policy != null) { expiredPasswordsPolicyValue = policy.getExpiredPasswords(); } if (expiredPasswordsPolicyValue != -1) { user.getCredentials().remove(credentialEntity); credentialEntity.setType(UserCredentialModel.PASSWORD_HISTORY); user.getCredentials().add(credentialEntity); List<CredentialEntity> credentialEntities = getCredentialEntities(user, UserCredentialModel.PASSWORD_HISTORY); if (credentialEntities.size() > expiredPasswordsPolicyValue - 1) { user.getCredentials() .removeAll( credentialEntities.subList( expiredPasswordsPolicyValue - 1, credentialEntities.size())); } credentialEntity = setCredentials(user, cred); setValue(credentialEntity, cred); em.persist(credentialEntity); user.getCredentials().add(credentialEntity); } else { List<CredentialEntity> credentialEntities = getCredentialEntities(user, UserCredentialModel.PASSWORD_HISTORY); if (credentialEntities != null && credentialEntities.size() > 0) { user.getCredentials().removeAll(credentialEntities); } setValue(credentialEntity, cred); } } }
/** * Update the TOTP for this account. * * <p>form parameters: * * <p>totp - otp generated by authenticator totpSecret - totp secret to register * * @param formData * @return */ @Path("totp") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response processTotpUpdate(final MultivaluedMap<String, String> formData) { if (auth == null) { return login("totp"); } require(AccountRoles.MANAGE_ACCOUNT); String action = formData.getFirst("submitAction"); if (action != null && action.equals("Cancel")) { setReferrerOnPage(); return account.createResponse(AccountPages.TOTP); } csrfCheck(formData); UserModel user = auth.getUser(); String totp = formData.getFirst("totp"); String totpSecret = formData.getFirst("totpSecret"); if (Validation.isBlank(totp)) { setReferrerOnPage(); return account.setError(Messages.MISSING_TOTP).createResponse(AccountPages.TOTP); } else if (!CredentialValidation.validOTP(realm, totp, totpSecret)) { setReferrerOnPage(); return account.setError(Messages.INVALID_TOTP).createResponse(AccountPages.TOTP); } UserCredentialModel credentials = new UserCredentialModel(); credentials.setType(realm.getOTPPolicy().getType()); credentials.setValue(totpSecret); session.users().updateCredential(realm, user, credentials); user.setOtpEnabled(true); // to update counter UserCredentialModel cred = new UserCredentialModel(); cred.setType(realm.getOTPPolicy().getType()); cred.setValue(totp); session.users().validCredentials(realm, user, cred); event.event(EventType.UPDATE_TOTP).client(auth.getClient()).user(auth.getUser()).success(); setReferrerOnPage(); return account.setSuccess(Messages.SUCCESS_TOTP).createResponse(AccountPages.TOTP); }
@Test public void testUsers() { UserModel r1user1 = session.users().getUserByUsername("user1", realm1); UserModel r2user1 = session.users().getUserByUsername("user1", realm2); Assert.assertEquals(r1user1.getUsername(), r2user1.getUsername()); Assert.assertNotEquals(r1user1.getId(), r2user1.getId()); // Test password r1user1.updateCredential(UserCredentialModel.password("pass1")); r2user1.updateCredential(UserCredentialModel.password("pass2")); Assert.assertTrue( session .users() .validCredentials(session, realm1, r1user1, UserCredentialModel.password("pass1"))); Assert.assertFalse( session .users() .validCredentials(session, realm1, r1user1, UserCredentialModel.password("pass2"))); Assert.assertFalse( session .users() .validCredentials(session, realm2, r2user1, UserCredentialModel.password("pass1"))); Assert.assertTrue( session .users() .validCredentials(session, realm2, r2user1, UserCredentialModel.password("pass2"))); // Test searching Assert.assertEquals(2, session.users().searchForUser("user", realm1).size()); commit(); realm1 = model.getRealm("id1"); realm2 = model.getRealm("id2"); session.users().removeUser(realm1, r1user1); UserModel user2 = session.users().getUserByUsername("user2", realm1); session.users().removeUser(realm1, user2); Assert.assertEquals(0, session.users().searchForUser("user", realm1).size()); Assert.assertEquals(2, session.users().searchForUser("user", realm2).size()); }
private CredentialEntity setCredentials(UserEntity user, UserCredentialModel cred) { CredentialEntity credentialEntity = new CredentialEntity(); credentialEntity.setType(cred.getType()); credentialEntity.setDevice(cred.getDevice()); return credentialEntity; }
/** * Update account password * * <p>Form params: * * <p>password - old password password-new pasword-confirm * * @param formData * @return */ @Path("password") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response processPasswordUpdate(final MultivaluedMap<String, String> formData) { if (auth == null) { return login("password"); } require(AccountRoles.MANAGE_ACCOUNT); String action = formData.getFirst("submitAction"); if (action != null && action.equals("Cancel")) { setReferrerOnPage(); return account.createResponse(AccountPages.PASSWORD); } csrfCheck(formData); UserModel user = auth.getUser(); boolean requireCurrent = isPasswordSet(user); account.setPasswordSet(requireCurrent); String password = formData.getFirst("password"); String passwordNew = formData.getFirst("password-new"); String passwordConfirm = formData.getFirst("password-confirm"); if (requireCurrent) { if (Validation.isBlank(password)) { setReferrerOnPage(); return account.setError(Messages.MISSING_PASSWORD).createResponse(AccountPages.PASSWORD); } UserCredentialModel cred = UserCredentialModel.password(password); if (!session.users().validCredentials(realm, user, cred)) { setReferrerOnPage(); return account .setError(Messages.INVALID_PASSWORD_EXISTING) .createResponse(AccountPages.PASSWORD); } } if (Validation.isEmpty(passwordNew)) { setReferrerOnPage(); return account.setError(Messages.MISSING_PASSWORD).createResponse(AccountPages.PASSWORD); } if (!passwordNew.equals(passwordConfirm)) { setReferrerOnPage(); return account .setError(Messages.INVALID_PASSWORD_CONFIRM) .createResponse(AccountPages.PASSWORD); } try { session.users().updateCredential(realm, user, UserCredentialModel.password(passwordNew)); } catch (ModelReadOnlyException mre) { setReferrerOnPage(); return account.setError(Messages.READ_ONLY_PASSWORD).createResponse(AccountPages.PASSWORD); } catch (ModelException me) { logger.error("Failed to update password", me); setReferrerOnPage(); return account .setError(me.getMessage(), me.getParameters()) .createResponse(AccountPages.PASSWORD); } catch (Exception ape) { logger.error("Failed to update password", ape); setReferrerOnPage(); return account.setError(ape.getMessage()).createResponse(AccountPages.PASSWORD); } List<UserSessionModel> sessions = session.sessions().getUserSessions(realm, user); for (UserSessionModel s : sessions) { if (!s.getId().equals(auth.getSession().getId())) { AuthenticationManager.backchannelLogout( session, realm, s, uriInfo, clientConnection, headers, true); } } event.event(EventType.UPDATE_PASSWORD).client(auth.getClient()).user(auth.getUser()).success(); setReferrerOnPage(); return account .setPasswordSet(true) .setSuccess(Messages.ACCOUNT_PASSWORD_UPDATED) .createResponse(AccountPages.PASSWORD); }
public UserCredentialModel generateSecret(OAuthClientModel app) { UserCredentialModel secret = UserCredentialModel.generateSecret(); app.setSecret(secret.getValue()); return secret; }