Search in sources :

Example 1 with KeystorePasswordHolder

use of won.owner.model.KeystorePasswordHolder in project webofneeds by researchstudio-sat.

the class KeystoreEnabledPersistentRememberMeServices method processAutoLoginCookie.

@Transactional
protected UserDetails processAutoLoginCookie(String[] cookieTokens, HttpServletRequest request, HttpServletResponse response) {
    if (cookieTokens.length != 2) {
        throw new InvalidCookieException("Cookie token did not contain " + 2 + " tokens, but contained '" + Arrays.asList(cookieTokens) + "'");
    }
    final String presentedSeries = cookieTokens[0];
    final String presentedToken = cookieTokens[1];
    TransactionTemplate transactionTemplate = new TransactionTemplate(platformTransactionManager);
    return transactionTemplate.execute(new TransactionCallback<UserDetails>() {

        @Override
        public UserDetails doInTransaction(TransactionStatus status) {
            Optional<PersistentLogin> persistentLoginOpt = persistentLoginRepository.findById(presentedSeries);
            if (persistentLoginOpt.isEmpty()) {
                // No series match, so we can't authenticate using this cookie
                throw new RememberMeAuthenticationException("No persistent token found for series id: " + presentedSeries);
            }
            PersistentLogin persistentLogin = persistentLoginOpt.get();
            // We have a match for this user/series combination
            if (!presentedToken.equals(persistentLogin.getToken())) {
                // Token doesn't match series value. Delete all logins for this user and throw
                // an exception to warn them.
                persistentLoginRepository.deleteByUsername(persistentLogin.getUsername());
                throw new CookieTheftException(messages.getMessage("PersistentTokenBasedRememberMeServices.cookieStolen", "Invalid remember-me token (Series/token) mismatch. Implies previous cookie theft attack."));
            }
            if (persistentLogin.getLastUsed().getTime() + getTokenValiditySeconds() * 1000L < System.currentTimeMillis()) {
                throw new RememberMeAuthenticationException("Remember-me login has expired");
            }
            // *same* series number.
            if (logger.isDebugEnabled()) {
                logger.debug("Refreshing persistent login token for user '" + persistentLogin.getUsername() + "', series '" + persistentLogin.getSeries() + "'");
            }
            // ------------- begin: added for WoN -----------------------
            // fetch the password from the keystore_password table
            // using the value of the 'wonUnlock' coookie as key
            String unlockKey = extractUnlockCookie(request);
            if (unlockKey == null) {
                // we did not find the unlock cookie - something is wrong.
                throw new CookieTheftException("The rememberMe cookie was ok but no unlock cookie was found.");
            }
            KeystorePasswordHolder keystorePasswordHolder = persistentLogin.getKeystorePasswordHolder();
            String keystorePassword = keystorePasswordHolder.getPassword(unlockKey);
            // update the persistent login: new date, new token, and change unlock key for
            // keystore password
            persistentLogin.setLastUsed(new Date());
            persistentLogin.setToken(generateTokenData());
            persistentLogin.setKeystorePasswordHolder(keystorePasswordHolder);
            String newUnlockKey = KeystorePasswordUtils.generatePassword(256);
            keystorePasswordHolder.setPassword(keystorePassword, newUnlockKey);
            try {
                persistentLoginRepository.save(persistentLogin);
                addCookies(persistentLogin, newUnlockKey, request, response);
            } catch (Exception e) {
                logger.error("Failed to update token: ", e);
                throw new RememberMeAuthenticationException("Autologin failed due to data access problem");
            }
            User userDetails = (User) getUserDetailsService().loadUserByUsername(persistentLogin.getUsername());
            KeystoreHolder keystoreHolder = userDetails.getKeystoreHolder();
            KeyStore keystore;
            try {
                keystore = keystoreHolder.getKeystore(keystorePassword);
            } catch (Exception e) {
                logger.error("Failed to load keystore: ", e);
                throw new RememberMeAuthenticationException("Autologin failed due to data access problem");
            }
            KeystoreEnabledUserDetails keystoreEnabledUserDetails = new KeystoreEnabledUserDetails((User) userDetails, keystore, keystorePassword);
            keystore = null;
            keystorePassword = null;
            return keystoreEnabledUserDetails;
        // delete the password
        }
    });
}
Also used : User(won.owner.model.User) Optional(java.util.Optional) TransactionTemplate(org.springframework.transaction.support.TransactionTemplate) TransactionStatus(org.springframework.transaction.TransactionStatus) PersistentLogin(won.owner.model.PersistentLogin) KeystorePasswordHolder(won.owner.model.KeystorePasswordHolder) KeyStore(java.security.KeyStore) Date(java.util.Date) UserDetails(org.springframework.security.core.userdetails.UserDetails) KeystoreHolder(won.owner.model.KeystoreHolder) Transactional(org.springframework.transaction.annotation.Transactional)

Example 2 with KeystorePasswordHolder

use of won.owner.model.KeystorePasswordHolder in project webofneeds by researchstudio-sat.

the class KeystoreEnabledPersistentRememberMeServices method onLoginSuccess.

/**
 * Creates a new persistent login token with a new series number, stores the
 * data in the persistent token repository and adds the corresponding cookie to
 * the response.
 */
@Transactional
protected void onLoginSuccess(HttpServletRequest request, HttpServletResponse response, Authentication successfulAuthentication) {
    String username = successfulAuthentication.getName();
    KeystoreEnabledUserDetails keystoreEnabledUserDetails = (KeystoreEnabledUserDetails) successfulAuthentication.getPrincipal();
    logger.debug("Creating new persistent login for user " + username);
    PersistentLogin persistentLogin = new PersistentLogin();
    persistentLogin.setUsername(username);
    persistentLogin.setSeries(generateSeriesData());
    persistentLogin.setToken(generateTokenData());
    persistentLogin.setLastUsed(new Date());
    String newUnlockKey = KeystorePasswordUtils.generatePassword(KeystorePasswordUtils.KEYSTORE_PASSWORD_BYTES);
    KeystorePasswordHolder keystorePasswordHolder = new KeystorePasswordHolder();
    keystorePasswordHolder.setPassword(keystoreEnabledUserDetails.getKeystorePassword(), newUnlockKey);
    persistentLogin.setKeystorePasswordHolder(keystorePasswordHolder);
    try {
        persistentLoginRepository.save(persistentLogin);
        addCookies(persistentLogin, newUnlockKey, request, response);
    } catch (Exception e) {
        logger.error("Failed to update token: ", e);
        throw new RememberMeAuthenticationException("Autologin failed due to data access problem");
    }
}
Also used : PersistentLogin(won.owner.model.PersistentLogin) KeystorePasswordHolder(won.owner.model.KeystorePasswordHolder) Date(java.util.Date) Transactional(org.springframework.transaction.annotation.Transactional)

Example 3 with KeystorePasswordHolder

use of won.owner.model.KeystorePasswordHolder in project webofneeds by researchstudio-sat.

the class UserService method generateRecoveryKey.

/**
 * Generates a new recovery key for the user
 */
@Transactional(propagation = Propagation.REQUIRED)
public String generateRecoveryKey(String email, String password) throws UserNotFoundException, IncorrectPasswordException {
    logger.debug("changing password for user {}", email);
    User user = getByUsernameWithKeystorePassword(email);
    if (user == null) {
        throw new UserNotFoundException("cannot generate recovery key: user not found");
    }
    PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    if (!passwordEncoder.matches(password, user.getPassword())) {
        throw new IncorrectPasswordException("cannot generate recovery key: incorrect password");
    }
    KeystorePasswordHolder keystorePasswordHolder = user.getKeystorePasswordHolder();
    KeystoreHolder keystoreHolder = user.getKeystoreHolder();
    String keystorePassword = keystorePasswordHolder.getPassword(password);
    StringBuilder sb = new StringBuilder();
    sb.append("MY__").append(randomStringGenerator.nextString(4)).append("_").append(randomStringGenerator.nextString(4)).append("_").append(randomStringGenerator.nextString(4)).append("_").append(randomStringGenerator.nextString(4)).append("__KEY");
    String recoveryKey = sb.toString();
    KeystorePasswordHolder recoverableKeystorePasswordHolder = new KeystorePasswordHolder();
    recoverableKeystorePasswordHolder.setPassword(keystorePassword, recoveryKey);
    keystorePasswordRepository.save(recoverableKeystorePasswordHolder);
    user.setRecoverableKeystorePasswordHolder(recoverableKeystorePasswordHolder);
    userRepository.save(user);
    return recoveryKey;
}
Also used : User(won.owner.model.User) BCryptPasswordEncoder(org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder) PasswordEncoder(org.springframework.security.crypto.password.PasswordEncoder) KeystoreHolder(won.owner.model.KeystoreHolder) ExpensiveSecureRandomString(won.protocol.util.ExpensiveSecureRandomString) KeystorePasswordHolder(won.owner.model.KeystorePasswordHolder) BCryptPasswordEncoder(org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder) Transactional(org.springframework.transaction.annotation.Transactional)

Example 4 with KeystorePasswordHolder

use of won.owner.model.KeystorePasswordHolder in project webofneeds by researchstudio-sat.

the class UserService method registerUser.

/**
 * Registers the specified user with password and an optional role. Assumes
 * values have already been checked for syntactic validity.
 *
 * @param email
 * @param password
 * @param role
 * @throws UserAlreadyExistsException
 * @return the created User
 */
public User registerUser(String email, String password, String role, String privateId) throws UserAlreadyExistsException {
    User user = getByUsername(email);
    if (user != null) {
        throw new UserAlreadyExistsException();
    }
    try {
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        user = new User(email, passwordEncoder.encode(password), role);
        user.setEmail(email);
        if (privateId != null) {
            user.setPrivateId(privateId);
        }
        // transfer only available when flag is set therefore we can just set
        user.setAcceptedTermsOfService(true);
        // this
        // to true (i think)
        KeystorePasswordHolder keystorePassword = new KeystorePasswordHolder();
        // generate a password for the keystore and save it in the database, encrypted
        // with a symmetric key
        // derived from the user's password
        keystorePassword.setPassword(KeystorePasswordUtils.generatePassword(KeystorePasswordUtils.KEYSTORE_PASSWORD_BYTES), password);
        // keystorePassword = keystorePasswordRepository.save(keystorePassword);
        // generate the keystore for the user
        KeystoreHolder keystoreHolder = new KeystoreHolder();
        try {
            // create the keystore if it doesnt exist yet
            keystoreHolder.getKeystore(keystorePassword.getPassword(password));
        } catch (Exception e) {
            throw new IllegalStateException("could not create keystore for user " + email);
        }
        // keystoreHolder = keystoreHolderRepository.save(keystoreHolder);
        user.setKeystorePasswordHolder(keystorePassword);
        user.setKeystoreHolder(keystoreHolder);
        return save(user);
    } catch (DataIntegrityViolationException e) {
        // username is already in database
        throw new UserAlreadyExistsException();
    }
}
Also used : User(won.owner.model.User) BCryptPasswordEncoder(org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder) PasswordEncoder(org.springframework.security.crypto.password.PasswordEncoder) KeystoreHolder(won.owner.model.KeystoreHolder) KeystorePasswordHolder(won.owner.model.KeystorePasswordHolder) BCryptPasswordEncoder(org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder) KeyStoreException(java.security.KeyStoreException) DataIntegrityViolationException(org.springframework.dao.DataIntegrityViolationException) UnrecoverableKeyException(java.security.UnrecoverableKeyException) KeyStoreIOException(won.owner.model.KeyStoreIOException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) DataIntegrityViolationException(org.springframework.dao.DataIntegrityViolationException)

Example 5 with KeystorePasswordHolder

use of won.owner.model.KeystorePasswordHolder in project webofneeds by researchstudio-sat.

the class UserService method changePassword.

/**
 * Changes the specified user's password from old to new, changes user's key
 * store password and invalidates all persistent logins.
 *
 * @param username
 * @param newPassword
 * @param oldPassword
 * @throws UserNotFoundException when the private User is not found
 * @throws KeyStoreIOException if something goes wrong loading or saving the
 * keystore
 * @throws IncorrectPasswordException if the old password is not the actual old
 * password of the user
 */
@Transactional(propagation = Propagation.REQUIRED)
public User changePassword(String username, String newPassword, String oldPassword) throws UserNotFoundException, KeyStoreIOException, IncorrectPasswordException {
    logger.debug("changing password for user {}", username);
    PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    User user = getByUsernameWithKeystorePassword(username);
    if (user == null) {
        throw new UserNotFoundException("cannot change password: user not found");
    }
    if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
        throw new IncorrectPasswordException("cannot change password: old password is incorrect");
    }
    KeystorePasswordHolder keystorePasswordHolder = user.getKeystorePasswordHolder();
    String oldKeystorePassword = keystorePasswordHolder.getPassword(oldPassword);
    logger.debug("re-encrypting keystore for user {} with new keystore password", username);
    String newKeystorePassword = changeKeystorePassword(user, oldKeystorePassword);
    // everything has worked so far, now make the changes
    user.setPassword(passwordEncoder.encode(newPassword));
    keystorePasswordHolder.setPassword(newKeystorePassword, newPassword);
    user.setKeystorePasswordHolder(keystorePasswordHolder);
    // we delete the recoverable keystore key as it will no longer work
    user.setRecoverableKeystorePasswordHolder(null);
    save(user);
    logger.debug("password changed for user {}", username);
    // persistent logins won't work any more as we changed the keystore password, so
    // let's delete them
    persistentLoginRepository.deleteByUsername(username);
    return user;
}
Also used : User(won.owner.model.User) BCryptPasswordEncoder(org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder) PasswordEncoder(org.springframework.security.crypto.password.PasswordEncoder) ExpensiveSecureRandomString(won.protocol.util.ExpensiveSecureRandomString) KeystorePasswordHolder(won.owner.model.KeystorePasswordHolder) BCryptPasswordEncoder(org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder) Transactional(org.springframework.transaction.annotation.Transactional)

Aggregations

KeystorePasswordHolder (won.owner.model.KeystorePasswordHolder)10 User (won.owner.model.User)9 BCryptPasswordEncoder (org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder)7 PasswordEncoder (org.springframework.security.crypto.password.PasswordEncoder)7 KeystoreHolder (won.owner.model.KeystoreHolder)6 Transactional (org.springframework.transaction.annotation.Transactional)5 DataIntegrityViolationException (org.springframework.dao.DataIntegrityViolationException)4 ExpensiveSecureRandomString (won.protocol.util.ExpensiveSecureRandomString)4 KeyStore (java.security.KeyStore)2 Date (java.util.Date)2 PersistentLogin (won.owner.model.PersistentLogin)2 URISyntaxException (java.net.URISyntaxException)1 KeyStoreException (java.security.KeyStoreException)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 UnrecoverableKeyException (java.security.UnrecoverableKeyException)1 Optional (java.util.Optional)1 Transactional (javax.transaction.Transactional)1 BadCredentialsException (org.springframework.security.authentication.BadCredentialsException)1 UsernamePasswordAuthenticationToken (org.springframework.security.authentication.UsernamePasswordAuthenticationToken)1 UserDetails (org.springframework.security.core.userdetails.UserDetails)1