Sprawdzenie poprawności hasła.

0

Cześć.
Piszę sobie nieduży projekt przy użyciu SpringMVC + Hibernate + MySql.

Trochę od tyłu się za to zabrałem ale zrobiłem sobie najpierw logowanie do aplikacji za pomocą Spring Security oraz UserDetails.
Aktualnie tworzę rejestrację.
Walidacja pól odbywa się przy pomocy hibernate validation.
Doszedłem do momentu sprawdzania poprawności podania 2 haseł (czy są takie same). Zrobiłem to dość łopatologicznie ponieważ dodałem do modelu User pole:

@Transient
private String confirmPassword;

Później w __kontrolerze __ je porównuje:

 if (Administrator.getPassword().equals(Administrator.getConfirmPassword())==false){
        model.addAttribute("error","Twoje hasła różnią się od siebie!");
}

Ogólnie rozwiązanie działa aczkolwiek wydaje mi się że nie jest ono do końca odpowiednie.
Jeśli jest coś lepszego to może ktoś mógłby podpowiedzieć co i jak (nie chodzi mi o gotowca tylko wskazówkę).

Pytanie numer 2. Mój projekt składa się z Modeli klas które odwzorowują tabelę w bazie, do tego mam DAO oraz Service. No i oczywiście kontrolery.
Jeśli chciałbym wykonywać jakieś operacje na obiekcie X (cokolwiek to może być, np sprawdzenie czy login nie składa się ze słów wulgarnych) to w którym miejscu powinienem pisać metodę sprawdzającą? Wydaje mi się że implementacja powinna być w DAO a Serwis powinien delegować do określonej metody w DAO. Aczkolwiek nie jest to operacja wykonywana na bazie danych a więc pewności nie mam. Chodzi mi po prostu o dobrą praktykę a nie klepanie kodu byle gdzie byle działało.

Pozdrawiam,
~eL

0
  1. Hasła w plain-text? Nie będę tego nawet komentował ;]
  2. Powinieneś mieć jakiś LoginService oczywiście. Logiki NIGDY nie trzymasz w kontrolerze!
  3. Walidacje rób za pomocą @Valid i waliduj wartości które przychodzą z formularza do kontrolera jako jakies beany.
0
Shalom napisał(a):
  1. Hasła w plain-text? Nie będę tego nawet komentował ;]

Może po prostu przyjmijmy na wstępie że nie każdy spędził nad kodem X lat i niektórzy dopiero zaczynają ;) A to że pytam to raczej świadczy tylko o tym że zależy mi żeby pisać to dobrze a nie klepać i uczyć się złych nawyków. A że niestety uczę się SAM z książek/tutoriali to gafy się zdarzają.

Shalom napisał(a):
  1. Powinieneś mieć jakiś LoginService oczywiście. Logiki NIGDY nie trzymasz w kontrolerze!

Czyli np tworzę sobie jakiś Serwis który będzie odpowiadał za określone operację (np sprawdzanie czy użytkownik nie podał słowa wulgarnego, sprawdzenie czy taki użytkownik już istnieje etc) i tam piszę wszystkie metody?

Shalom napisał(a):
  1. Walidacje rób za pomocą @Valid i waliduj wartości które przychodzą z formularza do kontrolera jako jakies beany.

Tak też robię. Podstawowa walidacja sprawdzania czy wszystkie formy zostały wypełnione itp odbywa się przy pomocy @Valid.

0
  1. słowa klucze na dziś: hash, salt
  2. Sprawdzanie wulgarności spokojnie możesz w zwykłym walidatorze zmieścić. Ale już próba zalogowania użytkownika powinna być w osobnym serwisie a nie w kontrolerze.
0
Shalom napisał(a):
  1. słowa klucze na dziś: hash, salt

Jeśli chodzi o hashe haseł to w bazie takowe przechowuję a potem przy pomocy Spring Security decoduje je przy pomocy encodera:

 <security:password-encoder hash="md5"/>
Shalom napisał(a):

Sprawdzanie wulgarności spokojnie możesz w zwykłym walidatorze zmieścić. Ale już próba zalogowania użytkownika powinna być w osobnym serwisie a nie w kontrolerze.

Trochę się nie rozumiemy. Zachowuję pewną strukturę. Mam obiekty DAO oraz serwisy. Większość z serwisów deleguje jedynie zadania do obiektów DAO. Logowanie natomiast mam zrobione przy pomocy Spring Security i posiadam serwis który implementuje UserDetailsService I to wiem że jest dobrze. Pytanie tylko gdzie powinienem pisać metody które nie działają na bazie danych a odwołują się np do POJO.
Np.
Mam Controller:

@RequestMapping(value = "/registerAdministrator", method = RequestMethod.POST)
    private ModelAndView saveAdministrator(@Valid @ModelAttribute("Administrator") Person Administrator, BindingResult result){

if(........){
personService.addPerson(Administrator);
}

return new ModelAndView("success");

Po wypełnieniu formularza rejestracyjnego kontroler wczytuje obiekt i zanim doda go do bazy, chciałbym sprawdzić czy np login nie zawiera wulgaryzmów. W którym miejscu więc powinienem dodać metodę która zwróci mi np true/false w zależności czy wulgaryzmy się pojawiły czy nie (po odwołaniu się do niej w IF)? Mam tworzyć nowy serwis lub metodę napisać w kontrolerze poniżej czy jak to powinno wyglądać żeby zachować ład i porządek?

0

Ustaw PasswordEncoder na BCrypta lub coś silniejszego niż MD5 które nie nadaje się do hashowania haseł

0

@eL no ale czemu tego wulgaryzmu nie sprawdza walidator?

0

@NoZi Chciałem i pierwotnie tak ustawiłem. Niestety nie wiem dlaczego ale intellij podświetla mi słowo bcrypt na czerwono z dopiską "Unknow enum value bcrypt". Nie miałem na razie czasu dochodzić czemu tak kaprysi więc póki co ustawiłem md5. Aczkolwiek racja, za dobre to to nie jest więc później będę szukał rozwiązania.

@Shalom te wulgaryzmy to tak naprawdę tylko przykład. Chodzi mi po prostu o to w którym miejscu powinno się pisać rzeczy takie jak np walidator wulgaryzmów czy inne metody które nie działają na bazie (więc nie widzę sensu pisania ich w klasie DAO) a pracują na POJO.

0

@eL OMG chłopie to napisz konkretnie JAKIE rzeczy. Bo walidator wylgaryzmów należy napisać jako walidator. A na przykład jakieś rzeczy związane z logiką "biznesową" jako serwisy. Dostęp do bazy nie ma tu absolutnie nic do rzeczy. Ot czasem logika potrzebuje coś przechowywać persystentnie, czasem nie. Nie jest to żadna reguła.
Różne rzeczy będą w róznych miejscach, w zależności od tego o jakie operacje chodzi!

0
Shalom napisał(a):

@eL OMG chłopie to napisz konkretnie JAKIE rzeczy.

Konkretnie np potrzebuję teraz taką rzecz.
Mam Osobę która ma RoleAdmin.
Ta osoba może dodać do bazy rekordy które są przypisane do niej.
Panel Administratora mam zabezpieczony za pomocą Spring Security:

 <security:intercept-url pattern="/PanelAdmin**" access="hasRole('ROLE_ADMIN')"/>

Po wejściu do panelu mam listę obiektów. Obok każdego z nich url: Edytuj | Usuń
Usuwam je za pomocą:

<a href="delete?idUser=${idUser}>Usun</a>

Aczkolwiek nie jest to dobrze ponieważ tak naprawdę każdy kto posiada uprawnienia Role Admin może wejśc na stronę np:
localhost:2233/PanelAdmin/delete?id=14
i usuwać obiekty.

Chciałbym zabezpieczyć to w taki sposób aby tylko osoba która utworzyła dany rekord mogła nim zarządzać.
Stworzyłem w kontrolerze metodę

private boolean SprawdzAutora(int idUsuwanego, int idZalogowanego)

idUsuwanego pobieram z URL a idZalogowanego za pomocą

request.getUserPrincipal().getName().getId()

Zanim obiekt zostanie usunięty, metoda sprawdza czy idZalogowanego znajduje się na liście obiektów utworzonych przez zalogowanego i musi zwrócić true

Tylko nie mam pojęcia czy to rozwiązanie ma sens i czy powinno znaleźć się w kontrollerze.

0

Tylko nie mam pojęcia czy to rozwiązanie ma sens i czy powinno znaleźć się w kontrollerze.

Mam nadzieję że to taki tylko żarcik. Wysyłasz request o usunięcie do UserService a UserService zwraca informacje o tym czy operacja sie powiodła czy nie. To przecież NIE JEST ŻADNA WALIDACJA danych wejściowych, tylko realizacja usługi z logiki biznesowej!

0

@Shalom O walidacji pisałem wcześniej, później zapytałeś mnie czego konkretnie nie wiem gdzie umieścić więc zapytałem o coś innego ponieważ z tamtą sprawą sobie poradziłem...

Okej czyli przyjmijmy że mam taką strukturę:

  • Model (odwzorowanie entity)
  • DAO który teraz zawiera krótko:
@Override
private void editUser(User user)
{
Session session = this.sf.getCurrentSession();
session.update(user);
}
  • Service który w zasadzie tylko deleguje do DAO:
private UserDAO userDAO;
@Transactional
@Override
private void editUser(User user)
{
this.userDAO.editUser(User user);
}

Więc z tego co rozumiem to powinienem w DAO pobrać zalogowanego użytkownika, sprawdzić czy może on edytować tego użytkownika i jeśli tak to to zrobić a metoda powinna zwrócić true. W przeciwnym wypadku false.

Tak będzie poprawnie?

0

Czy ty czytasz moje posty? DAO zawiera logikę dotyczącą persystentnych danych. Nic więcej. Pobieranie z bazy / zapisywanie do bazy. Koniec. Kropka. Logika aplikacji zawarta jest w serwisach. Co tu jest tak trudnego to zrozumienia?

0

Wiem że komuś kto siedzi w tym pewnie X lat pewne sprawy wydają się być żałośnie proste, ale wierz mi że jak by Cię na studiach na przedmiocie "Bazy Danych" uczyli Excela i musiałbyś do wszystkiego dochodzić od podstaw sam to byłoby Ci łatwiej nas szaraków zrozumieć :P .

Czyli w UserService sprawdzam czy UserX ma uprawnienia do edycji UseraY i jeśli wszystko gra to wykonuje

this.userDAO.editUser(User user);

a jeśli nie to zwraca false?

Mimo że frustrat z Ciebie straszny to dzięki stary za pomoc! :)

1

Generalnie tak. Jednocześnie zwracanie false niekoniecznie jest najlepszym rozwiązaniem, bo równie dobrze mógłbyś rzucać jakiś wyjątek, gdyby powodów mogło być więcej, ale w tej sytuacji false pewnie starczy. Ale pamiętaj żeby potem wyświetlić użytkownikowi jakis komunikat błędu :)

Nie frustrat, tylko 3 razy już w tym temacie to napisałem, a ty nadal o to samo pytasz...

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