luchob / softuni-music-db

Our workshop project for the course Spring Advanced 2021
3 stars 11 forks source link

При въвеждане на грешни данни изчезват линкове в navbar #4

Closed Elizabetaa closed 3 years ago

Elizabetaa commented 3 years ago

Проект: https://github.com/Elizabetaa/MotoTuning

luchob commented 3 years ago

Здравей! На пръв поглед нещата изглеждат ок, изключая повтарящите се dependencies в pom.xml. Довечера ще имам повечко време да разгледам и ще ти пиша. Съжалявам, но в момента съм малко притиснат от времето :-) Успешен ден и до после!

luchob commented 3 years ago

Здравейте!

Сега ми остана малко време и погледнах, решението е много близко до това, което Дойчо казва. А проблемът е много тънък и вината е моя, че не съм го забелязал. Ще го адресирам на следващата лекция подробно, защото е много важно.

Нека първо да опитам да обясня какво се случва... Говорихме за това, че Spring Security представлява една поредица от филтри, всеки от които помага за нещо. Един от тези филтри се нарича AnonymousAuthenticationFilter и се грижи ако юзъра е анонимен да попълни SecurityContextHolder-a с анонимна аутентикация. Това става, като зареждаш Sign in страницата, например. Ако си логнат пък, то друг филтър попълва истинската аутентикация, която не е анонимна и AnonymousAuthenticationFilter не се включва в играта. И в двата случая, обаче в SecurityContextHolder ИМА обект - аутентикация. Тъй... Thymeleaf Sercurity работи само ако има такъв обект аутентикация в SecurityContextHolder.

Какво става обаче, като се логваш и си сбъркаш паролата, например? Включва се друг филтър (UsernamePasswordAuthenticationFilter), който разчита на DaoAuthenticationProvider (това нещо, дето използва вашите UserDetailsService и PasswordEncoder), вижда се че юзъра си е сбъркал паролата и не попълва SecurityContextHolder-а с аутентикация. Той остава празен. Затова и Thymeleaf Sercurity повече не работи.

Знам, че звучи малко объркано, но нека да продължим. Тази настройка: failureForwardUrl("/users/signIn-error") препраща "вътрешно" (без да прави browser redirect) към signIn-error страницата и затова Thymeleaf Sercurity не работи - SecurityContextHolder е празен.

Ако я заменим с: failureUrl("/users/signIn-error") неуспешния логин ще завърши с статус 302 и браузъра ще се опита да редиректне с get (POST-redirect-GET) заявка към /users/signIn-error, ще има AnonymousAuthenticationFilter, всичко ще работи, обаче ще загубим потребителското име, което е много дразнещо.

Затова може да се модифицира малко решението на Дойчо и да променим пост мапинга по следния начин:

@PostMapping("/signIn-error")
    public ModelAndView failedLogin(@ModelAttribute("email")
                                           String email,
        RedirectAttributes attributes) {

        ModelAndView modelAndView = new ModelAndView();

        attributes.addFlashAttribute("filed", true);
        attributes.addFlashAttribute("email", email);

        modelAndView.setViewName("redirect:/users/signIn");

        return modelAndView;
    }

Така след неуспешния логин ще върнем 302, и браузъра ще направи редирект с подходящи флаш атрибути към sign in страницата...

Знам, че е малко объркано... но ще се опитам да го повторя на лекцията.

Благодаря на Елизабета за хубавия въпрос и се надявам скоро да може да гледам мотоциклети на сайта и :-) Ако има повече проблеми, драснете някой ред в това issue.

luchob commented 3 years ago

Приемам, че всичко е наред! Ако има някакви въпроси или все още не можеш да се справиш, не се колебай да пишеш тук. Ще направя pull request в проекта ти, ако това е необходимо.

Поздрави!