Edycja użytkownika wyłączając hasło.

0

Witam. Mam taką tabelę:

  create table users (

  id int not null primary key,
  username varchar2(40) not null unique,
  password varchar2(60) not null,
  firstName varchar2(40) not null,
  lastName varchar2(40) not null,
  personalId varchar2(11) unique,
  city varchar2(40),
  address varchar2(40),
  email varchar2(40) not null unique,
  phone varchar2(9) unique
); 

Aplikacja jest napisana w Springu z użyciem Spring Secyrity, w tabeli przechowuję hasła zahashowane algorytmem bcrypt. Wszystko jest ok, gdy chcę dodać nowego użytkownika bądź edytuje istniejącego wprowadzając nowe hasło. Problem pojawia się gdy w moim formularzu nie wprowadzę hasła, bo chcę zachować stare. Gdy dam edytuj bez wprowadzania hasła to shashuje mi hasha... Próbowałem uzyskać dostęp do hasła pobierając je z kontekstu, ale dostaję hasha z bazy, więc to mnie i tak nie ratuje.

    @RequestMapping(value = "/admin/editMe", method = RequestMethod.POST)
public String editMe(@ModelAttribute("user") UserDto userDto,
        BindingResult result) {
    EditUserValidator editUserValidator = new EditUserValidator();
    editUserValidator.validate(userDto, result);
    if (userDto.getPassword().isEmpty()) {
        Authentication auth = SecurityContextHolder.getContext()
                .getAuthentication();
        String username = auth.getName();
        User user = userService.findByUsername(username);
        System.out.println(user.getPassword());
        userDto.setPassword(user.getPassword());
    }
    if (result.hasErrors()) {
        return "admin/editme";
    } else {
        ErrorMessage errorMessage;
        User user = prepareModelUser(userDto);
        if ((errorMessage = userService.updateUser(user)) != null) {
            result.rejectValue(errorMessage.getPath(),
                    errorMessage.getDescription());
        }
        return "admin/editme";
    }
} 

Jak to zrealizować? Żeby można edytować użytkownika bez wprowadzania nowego hasła.

1

eeee ale wiesz, że możesz w bazie aktualizować zaledwie jedno pole nie musisz wszystkich? Robisz to wybiórczo odpowiednio pisząc zapytanie update.

0
mr_jaro napisał(a):

eeee ale wiesz, że możesz w bazie aktualizować zaledwie jedno pole nie musisz wszystkich? Robisz to wybiórczo odpowiednio pisząc zapytanie update.

userService.updateUser(user) wywołuje potem entityManager.merge(user). Nie piszę, żadnego zapytania.

0

No przecież Ci napisał, że tym sposobem updateujesz WSZYSTKO, a możesz zapytaniem

0
NoZi napisał(a):

No przecież Ci napisał, że tym sposobem updateujesz WSZYSTKO, a możesz zapytaniem

No tak mogę zapytaniem. Ale czy nie ma jakiegoś szybszego sposobu jak np, wyciągnięcie tego hasła i ustawienie go po prostu przed operacją edycji jeśli pole było puste?

1

A jak chcesz 'wyciagnac' haslo z jego hasha? Przeciez o to wlasnie chodzi w hashach zeby trudno/niemozliwe bylo z nich wyciagac hasla. Do tego powinny byc posolone zeby bylo bardzo trudne ich zcrackowanie (nie dzialaja rainbow tables itp.).
Hash to 'skrot', kazdy hash ma np. 32 znaki, bez wzgledu na oryginalna dlugosc hashowanego tekstu. Z tego wynika, ze tekst calej ksiazki, zhaszowany, rowniez bedzie mial 32 znaki. Jelsi z tych 32 znakow daloby sie wyciagnac oryginalny string, moglbys mi przeslac cale tomy encyklopedii sms-em - tylko 32 znaki, ja bym sobie 'wyciagnal' oryginalny tekst. Albo moglbys mi film podyktowac przez telefon ;d

Podejrzewam ze problem jest inny - jak zapisujesz usera, to to co jest w polu password jest przez springa kiedystam haszowane (pytanie kiedy, dawno sie tym nie zajmowalem). Wykonaj eksperyment: utworz usera, zapisz go zapamietujac przy okazji gdzies na boku jego haslo; nastepnie, wczytaj tego usera z bazy i porownaj oryginalne haslo z tym co ma user.password - podejrzewam ze wlasnie ten wczytany user bedzie mial w password skrot. Ergo: zapisanie i wczytanie encji usera nie jest idempotentne. Moim zdaniem to cos zlego, ale moze sie myle i spring security tego wymaga.
Tak czy siak, tak jak to robisz sie nie da.

0
the real mućka napisał(a):

Wykonaj eksperyment: utworz usera, zapisz go zapamietujac przy okazji gdzies na boku jego haslo; nastepnie, wczytaj tego usera z bazy i porownaj oryginalne haslo z tym co ma user.password - podejrzewam ze wlasnie ten wczytany user bedzie mial w password skrot. Ergo: zapisanie i wczytanie encji usera nie jest idempotentne. Moim zdaniem to cos zlego, ale moze sie myle i spring security tego wymaga.
Tak czy siak, tak jak to robisz sie nie da.

No właśnie o to chodzi, że user.password ma hasha i dlatego cały problem, bo jak nie zmieniam hasła to on hashuje hasha i wychodzi w ogóle coś niemożliwego. Gdyby w bazie był hasła zapisane normalnym tekstem problemu by nie było. No nic muszę sobie jakoś inaczej poradzić bo to wyciąganie hasła to rzeczywiście nie najlepszy pomysł.

Udało mi się obejść ten problem. Przy edycji usera zawsze hashowałem je od nowa, nawet jak przekazywałem stary hash i stad ten problem z hashowaniem hasha. Teraz sprawdzam czy przekazany user ma puste hasło.

			if (user.getPassword().isEmpty()) {
				User userTmp = findUser(user.getId());
				user.setPassword(userTmp.getPassword());
			} else {
				BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
				user.setPassword(passwordEncoder.encode(user.getPassword()));
			}
			userDao.updateUser(user); 
0

AA, czyli to nie spring security haszuje tylko ty sam musisz to robic. Czyli po prostu miales blad logiczny w aplikacji.
Nie podoba mi sie twoje rozwiazanie - w momencie zapisywania usera pobierasz go jeszcze raz z bazy zeby podstawic haslo itp. Nie mozesz pobrac usera i przed update sprawdzic czy on juz istnieje (update) czy jest nowy (save), i od tego uzalezniac czy haszowac czy nie?

0
the real mućka napisał(a):

AA, czyli to nie spring security haszuje tylko ty sam musisz to robic. Czyli po prostu miales blad logiczny w aplikacji.
Nie podoba mi sie twoje rozwiazanie - w momencie zapisywania usera pobierasz go jeszcze raz z bazy zeby podstawic haslo itp. Nie mozesz pobrac usera i przed update sprawdzic czy on juz istnieje (update) czy jest nowy (save), i od tego uzalezniac czy haszowac czy nie?

To jest wycinek z metody edytującej. Metoda tworząca usera jest osobno i nie ma w niej powyższego fragmentu.

0

Nie zmienia to faktu że wydajność w twoim kodzie leży i kwiczy ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1