W ostatnim czasie spotkałem się z potrzebą stworzenia mechanizmu uwierzytelniania użytkowników w aplikacji internetowej korzystając ze Spring Security. Po przebrnięciu przez dokumentację i kilka tutoriali okazuje się, ze nie jest to zbyt skomplikowana rzecz. Podstawową (bardzo ubogą lecz w pełni funkcjonalną) ochronę aplikacji działających w internecie można uzyskać w dodając raptem kilkanaście linii kodu. W tym artykule przedstawię jak tego dokonać w elementarny sposób.
Na wstępie zaznaczę, że swoją aplikację tworzę używając Spring Framework w wersji 3.1, do jej budowania używam Apache Maven 2.2.1, czyli taki standardowy obecnie zestaw narzędzi do rozwijania aplikacji internetowych w jawie. Chcąc uniknąć umieszczania kompletnego kodu całego programu, skupię się jedynie na rzeczach niezbędnych o które należy wzbogacić swoją aplikację.
Jeszcze tytułem wstępu krótko powiem o zasadzie działania Spring Security. Jego konfiguracja sprowadza się przede wszystkim do wypisania scieżek URI stron, które mają zostać chronione hasłem. Absolutnie nie jest konieczna jakakolwiek modyfikacja istniejącego już kodu. Natomiast cały proces wdrażania Spring Security składa się zasadniczo z trzech kroków:
- dodanie zależności do classpath
- skonfigurowanie filtrów w pliku web.xml oraz
- skonfigurowanie całego mechanizmu Security w pliku application-security.xml
Zacznijmy zatem od dodania niezbędnych zależności do maven'owego pliku pom.xml:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>
</dependency>
Kolejna rzecz to konfiguracja filtra. W pliku web.xml należy dodać element <filter/> oraz <filter-mapping/>:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
tutaj istotna jest sama nazwa filtru (a właściwie proxy), który oddeleguje zapytania pasujące do wzorca /* do filtru springSecurityFilterChain.
Dalszy etap to stworzenie nowego kontekstu spring'owego, który zostanie załadowany wraz ze startującą aplikacją. W pliku web.xml należy podać lokalizację pliku z kontekstem, np:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/application-security.xml
</param-value>
</context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/application-security.xml
</param-value>
</context-param>
oraz (jeśli jeszcze nie ma) loader kontekstu:
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
Utworzony plik application-security.xml jest klasycznym plikiem kontekstu spring'a i w zasadzie nic nie stoi na przeszkodzie aby jego zawartość wkleić bezpośrednio do głównego pliku kontekstowego tworzonej aplikacji. Należy jednak unikać takiego rozwiązania, gdyż nawet w prostych projektach konteksty potrafią bardzo szybko się rozrazstać do monstrualnych plików xml zawierających kilkaset czy nawet kilka tysięcy linii.
Zawartość pliku konfiguracyjnego application-security.xml powinna wyglądać mniej więcej tak:
<http auto-config="true">
<intercept-url pattern="/messages" access="ROLE_USER"/>
<intercept-url pattern="/messages" access="ROLE_USER"/>
<intercept-url pattern="/administration" access="ROLE_ADMIN"/>
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="admin" password="admin" authorities="ROLE_ADMIN"/>
<user name="pawel" password="secret" authorities="ROLE_USER"/>
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="admin" password="admin" authorities="ROLE_ADMIN"/>
<user name="pawel" password="secret" authorities="ROLE_USER"/>
<user name="guru" password="topsecret" authorities="ROLE_USER, ROLE_ADMIN"/>
</user-service>
</authentication-provider>
</authentication-manager>
</authentication-provider>
</authentication-manager>
oczywiście należy dodać odpowiednie definicje przestrzeni nazw zgodnie z dokumentacją.
Element <intercept-url/> w atrybucie pattern definiuje ścieżki URI do podstron, które mają być chronione, natomiast access to grupy (lub role) użytkowników, którzy mają do nich dostęp.
<authentication-provider> w najprostszej postaci dostarcza listy użytkowników, hasła i role do których należą. W bardziej złożonym (i częściej spotykanym) przypadku zdefiniowane są tu klasy obsługujące połączenie z bazą danych, serwerem LDAP lub wiele innych sposobów uwierzytelniania użytkowników. Jednak jest to temat na osobny artykuł.
To wszystko. Teraz wystarczy skompilować i uruchomić aplikację. Gdy będziemy próbować dostać się do stron /messages lub /administration Spring Security przekieruje nas do domyślnie wygenerowanej strony logowania znajdującej się pod adresem /spring_security_login:
W celu zakończenia sesji (wylogowania) należy w pasku przeglądarki wpisać adres: /j_spring_security_logout.
Oczywiśćie nic nie stoi na przeszkodzie aby stworzyć własny formularz logowania. Po więcej informacji polecam skorzystać z oficjalnego przewodnika na stronie http://springsource.org, a także samodzielnego eksprymentowania z modułem Spring Security.
Brak komentarzy:
Prześlij komentarz