Problem 5. SecurityFilter
Здравейте, колеги. Въпроса ми е свързан с последната задача от домашното към темата Containers, Filters and Sessions и по-скоро с условието на задачата.
The filter should take username and password from the request
If they exists and are correct (compare them to some username and password in the code) – add the user to the session and redirect to the HomePage
Някой може ли да ми обясни какво значи username and password да са correct? За мен това значи да се сравняват с регулярен израз ,но тук явно случая е друг?
String username = "admin";
String password = "admin";
И аз си мислех за хешмап но в крайна сметка хардкоднах стрингове, изхождайки от това, че в базата данни търсим точно за определен юзърнейм и винаги имаме 1 резултат (освен ако не ни е кофти валидацията или настройките на дб-то)
Да и аз съм със същите хардкорднати стойности! Но нещо ми се бъгна Еклипса и до последно не искаше да ми редиректва, и се оказа, че е от екшъна на формата!
Как таака от екшъна на формата? Може ли да поясниш малко?
Формата в HTML-а има action и method! Екшъна общо взето указва към къде да се редиректне по подразбиране при субмитване! Обаче екшъна на моята форма не позволяваше на филтъра да си свърши работата.
Като изтрих екшъна на формата и всичко си заработи както е замислено!
Формата без action няма много смисъл. Целта на action-a е да каже къде да се пратят данните от формата за обработката. Може да погледнете тук: http://www.w3schools.com/html/html_forms.asp за по - подробно описание на form тага и съответни input тагове. Другия параметър на формата е method. Той по подразбиране е GET. Какво се получава:
Ако имаме
<form action="pages/my_page.jsp"> <input name="username" type=text> <input name="some_param" type = text /> <input name="password" type = password /> <input type = submit value=submit /><form>
Когато натиснем submit ще ударим сървъра със:
http://MY_SERVER/pages/my_page.jsp?username="<username>&password=<password>&some_param=<some_param_inputed_by_user>"
От тук сървара ще потърси филтър който отговаря на подадения адрес, примерно @WebFilter("/pages/*") или @WebFilter("/pages/my_page.jsp") ... и ако намери такъв ще изпълни doFilter(...) функцията му, ако не ще потърси сървлет с анотация, която отговаря на подаденото url (както при анотацията на филтъра) и ще удари doGet(...) метода му или my_page.jsp файл в page директорията.
Което и да удари, със съответните параметри можем да разполагаме като кажем request.getParameter("...").
Ако кажем на същата форма, че method-a и е POST: Удряме сървъра на адрес: http://MY_SERVER/pages/my_page.jsp и подаваме същите параметри, отделно от url-a като body и разликата с горното е, че ако се удари сървлет ще се удари doPost метода му.
Когато имаме лични данни, като в случая парола, е хубаво да се ползва POST, за да не се подават тези данни през url-то.
Иначе за първоначалния въпрос, както е казал колегата b.yordanov, по - добре да се хардкоднат. Идеята на лекцията е да се разберат филтри и лисънари, а не да се търси хубав начин за съхраняване и проверка на логин информация.
И още един хубав въпрос повдигнат тук: Какво правим ако имаме подадени username, password и сесия със username в нея?
Тук има повече от един верен отговор. Може да тества поведението на други сайтове по въпроса. И тук как точно ще се държи сървъра е по - скоро тема за секюрити. В контекста на тази задача е въпрос на каквото и да е решение, което да не чупи сървъра.
Значи може и да не "удряме" нищо като нямаме екшън във формата и да си вземем параметрите, които ни трябват с getParameter! Метода ще свърши цялата работа като прати данните в сървъра за обработка!
Мда, прав си, може и без action! Тествах го с firefox. Ако няма подаден action, напрактика поведението е същото, като това дето съм описала, само, че удря сървъра със същия url в който е отворена и формата.
Да, понеже формата си има екшън по подразбиране! Но това може да се разбере когато се сблъска човек с даден проблем, затова по-добре се учи като се пише код! И аз тук споделях опит, който може да е полезен на някой в бъдеще!
При не зададен action на form тага, се извиква текущото url.
Тоест ако имаш login.jsp и дадеш submit, ще ти се зареди отново login.jsp със съответните GET параметри.
Аз "слушам" за логин параметрите във Filter-а.
Това ми е doFilter метода:
HttpServletRequest httpRequest = (HttpServletRequest) request;
String username = request.getParameter("username");
String password = request.getParameter("password");
if ((username != null) && (password != null)) {
if (username.equals("admin") && password.equals("password")) {
httpRequest.getSession().setAttribute("username", username);
((HttpServletResponse) response).sendRedirect(request
.getServletContext().getContextPath());
return;
}
} else {
if (httpRequest.getSession().getAttribute("username") == null) {
if (!httpRequest.getServletPath().equals("/Login.jsp")) {
((HttpServletResponse) response).sendRedirect(request
.getServletContext().getContextPath()+"/Login.jsp");
return;
}
}
}
chain.doFilter(request, response);
Точно така: Ако си на http://MY_SERVER/logn.jsp, която показва <form> ... </form> това ще субмитне параметрите от формата на адрес "/logn.jsp" или на сървъра отива http://MY_SERVER/login.jsp?username=.... (все едно имаш <form action="/login.jsp">). А после дали ще влезе в самия филтър зависи от параметъра в анотацията: @WebFilter("..."). Ако си сложил "/*" или "/login.jsp" ще мине от там и ще изпълни doFilter-a, където с getParameter("...") можеш да си ги обработваш (както си го и направил в момента).