W poprzednich częściach tej lekcji mówiliśmy o samej koncepcji Spring Security oraz o tym, jak skonfigurować aplikację, aby z niego korzystała. Dzisiaj dowiemy się, jak wykorzystać tą konfigurację w naszej aplikacji :)
Dzisiaj trzecia i ostatnia część tej lekcji — zobaczymy, jak używać SpringSecurity w praktyce w naszej aplikacji. Po tej lekcji będziesz wiedziała, jak zabezpieczyć wybrane strony, wyświetlić ładny formularz logowania i zmieniać zachowanie Spring Security. Przejdźmy więc do samej lekcji :)
Lekcja
Konfiguracja własnego formularza logowania
W poprzedniej lekcji korzystaliśmy z formularza logowania wygenerowanego przez Springa — dzisiaj zmienimy to w taki sposób, aby używać własnego.
Przede wszystkim potrzebujemy widoku, który będzie wyświetlał rzeczony formularz — nie musi to być jakiś specjalny widok, integracja polega na tym, że wysyłamy odpowiednio spreparowane dane pod odpowiedni adres. W tym miejscu zakładam, że sama dopasujesz swój szablon — przedstawiony przykład może wyglądać u Ciebie inaczej, ale realnie ważne są głównie atrybuty ‘name’ pól oraz ‘action’ całego formularza. Układ wizualny, kolejność pól i style nie mają znaczenia :) Będziemy więc pracować na poniższym przykładzie:
<c:set var="loginUrl"><c:url value="/login"/></c:set>
<form method="post" action="${loginUrl}">
<input type="text" name="email" />
<input type="password" name="password" />
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<input type="submit" value="Zaloguj" />
</form>
Pierwsza linia ustawia zmienną EL o nazwie loginUrl i wpisuje do niej wartość — adres URL wygenerowany dla adresu względnego /j_spring_security_check . Trzecia linijka od końca to zabezpieczenie przed CSRF — włączymy to zabezpieczenie w naszej konfiguracji.
CSRF to jedna z metod ataku na aplikacje webowe, który polega na takim przekierowaniu użytkownika (w sposób niewidoczny), żeby wykonał bez świadomości pewną akcję (np. nadał atakującemu dodatkowe uprawnienia). Więcej możesz znaleźc np. na wikipedii: http://pl.wikipedia.org/wiki/Cross-site_request_forgery .
W pliku spring-security zamieniamy poprzedni tag <http> na następujacy:
<http auto-config="true" use-expressions="true">
<form-login login-page="/login"
default-target-url="/profile"
authentication-failure-url="/login?error=1"
username-parameter="email"
password-parameter="password" />
<logout logout-success-url="/home" /> <!-- określamy przekierowanie po wylogowaniu -->
<csrf /> <!-- włączamy zabezpieczenie przed csrf -->
</http>
Mamy tutaj kilka dodatkowych elementów:
- logout — za pomocą atrybutu logout-success-url określamy adres, na jaki użytkownik będzie przekierowany po poprawnym wylogowaniu
- więcej opcji zostało opisane na stronie http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#nsa-logout
- csrf — ten tag aktywuje zabezpieczenie przed atakami CSRF. Niestety wymaga to, aby każdy formularz w naszej aplikacji zawierał linijkę (taką jak 3 od końca na powyższym przykładzie) — jest to unikalny token generowany za każdym razem przez naszą aplikację a następnie po przesłaniu formularza weryfikowany (automatycznie przez Spring Security)
- form-login — ten tag jest najbardziej interesujący, skonfigurujemy w nim kilka rzeczy:
- login-page — adres strony z formularzem logowania
- default-target-url — adres, na który użytkownik zostanie przekierowany po zalogowaniu (uwaga: domyślnie będzie to zabezpieczona strona, którą próbował odwiedzić, a która spowodowała przekierowanie na logowanie; jeśli takiej strony nie było, następuje przekierowanie na tą stronę)
- authentication-failure-url — adres, na który przekierowujemy, jeśli były błędy w logowaniu (np. zły login lub hasło)
- username-parameter, password-parameter — określają nazwy pól z loginem i hasłem (czyli w HTMLu przekłada się to na wartość atrybutu name dla odpowiednich tagów input)
- więcej informacji znajdziemy na stronie http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#nsa-form-login
W ten sposób skonfigurowaliśmy własny formularz logowania — prawda, że prosto? :) Przejdźmy teraz do zabezpieczania metod.
Zabezpieczanie metod — adnotacja @Secured
Aby korzystać z tej adnotacji musismy dodać jeszcze jedną rzecz — i uwaga, dodajemy ją tam, gdzie deklarujemy beany (np. kontrolery), a więc w naszym przypadku w pliku applicationContext.xml.
Musimy dodać poniższą linijkę:
<security:global-method-security secured-annotations="enabled" pre-post-annotations="enabled" />
Pamiętając, aby dodać prefiks security w naszym XML (na górze pliku dodajemy xmlns:security=”…”).
Pozwala to używać adnotacji @Secured nad naszymi metodami. Adnotacja ta przyjmuje jako parametry nazwy ról, które mają dostęp do tej funkcjonalności. Nazwy te są tymi, które pobieramy w drugim zapytaniu przy autoryzacji (patrz druga część tej lekcji).
W tym miejscu warto tez zapamiętać, że domyślnie niezalogowany użytkownik posiada role ROLE_ANONYMOUS (jeśli jest coś, co chcielibyśmy wyświetlać tylko niezalogowanym użytkownikom).
Korzystamy z danych o zalogowanym użytkowniku
W kodzie Javy
Bezpośrednio w Javie Spring udostępnia obiekt Authentication, który możemy pobrać w następujący sposób:
SecurityContextHolder.getContext().getAuthentication()
Posiada on pole principal, które może byc obiektem typu Principal, a może też być Stringiem (stąd deklaracja jako Object). Pole to jest Stringiem, jeżeli użytkownik nie jest zalogowany. Możemy więc używać tej właściwości do rozróżnienia, czy osoba korzystająca ze strony jest zalogowana czy też nie.
W widokach
W widokach mamy dostępne dwa tagi — jeden do kontrolowania wyświetlania pewnych elementów oraz drugi, do wyświetlania danych o zalogowanym użytkowniku.
<sec:authorize access="hasRole('ROLE_USER')">
Informacja tylko dla zalogowanych
</sec:authorize>
Powyższy kod wyświetli dany fragment tylko dla użytkowników, którzy posiadaja rolę ROLE_USER.
<sec:authentication property="principal.username" />
Z kolei ten kod pozwala wyświetlić informacje o zalogowanym użytkowniku (takie jak np. login użyty podczas logowania)
Jeśli uważasz powyższą lekcję za przydatną, mamy małą prośbę: polub nasz fanpage. Dzięki temu będziesz zawsze na bieżąco z nowymi treściami na blogu ( i oczywiście, z nowymi częściami kursu Javy). Dzięki!