Не зависящий от времени запрос для существующего и несуществующего пользователя с Spring Security - PullRequest
0 голосов
/ 14 января 2019

В моей службе аутентификации я пытаюсь получить пароль от моего Redis с помощью простого StringRedisTemplate объекта.
Затем я использую BCryptPasswordEncoder для сопоставления пароля.
Я понял, что существует разница во времени между несоответствием имени пользователя и несоответствием пароля.
Я читал некоторые статьи, в которых говорится, что имя пользователя не является секретным значением, и мне не о чем беспокоиться - я знаю об этом, но в моем случае я хочу, чтобы между обоими случаями не было разницы во времени.
Как я могу это сделать?

@PostMapping(value = "/auth", consumes = "application/json")
public ResponseEntity<?> isClientExists(@Valid @RequestBody User user) {
    //with redisTemplate.opsForValue().get(sha256Hex(userName)) :
    UserDetails user = redisClient.loadUserByUserName(user.getUserName()); 

    if (userNotFound(userFromDB)) {
        /* What should I add here to make it time-invariant query? */
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
    }
    if (!authenticateUser(user.getPassword(), userFromDB.getPassword())) {
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
    }

    return ResponseEntity.status(HttpStatus.OK).build();
}

private boolean userNotFound(UserDetails userFromDB) {
    return (userFromDB == null);
}

private boolean authenticateUser(String userPassword, String userFromDBPassword) {
    //with BCryptPasswordEncoder :
    return passwordEncoder.matches(userPassword, userFromDBPassword);
}

1 Ответ

0 голосов
/ 14 января 2019

Два подхода:

1) Выясните, сколько времени в среднем занимает вызов authenticateUser, и он спит так долго (хотя время, возможно, изменится при обновлении ЦП в будущем).

2) Просто сделайте еще один вызов authenticateUser со случайными данными и проигнорируйте результат.

...