Beispiel #1
0
 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();
  }
Beispiel #6
0
 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());
 }
Beispiel #7
0
  @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());
    }
  }
Beispiel #9
0
  @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();
  }
Beispiel #10
0
            @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();
  }
Beispiel #13
0
  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());
    }
  }
Beispiel #14
0
 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);
 }
Beispiel #15
0
            @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"));
            }
Beispiel #17
0
  /**
   * 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);
  }
Beispiel #18
0
  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);
      }
    }
  }
Beispiel #19
0
  /**
   * 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());
  }
Beispiel #21
0
 private CredentialEntity setCredentials(UserEntity user, UserCredentialModel cred) {
   CredentialEntity credentialEntity = new CredentialEntity();
   credentialEntity.setType(cred.getType());
   credentialEntity.setDevice(cred.getDevice());
   return credentialEntity;
 }
Beispiel #22
0
  /**
   * 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;
 }