Bezpieczeństwo aplikacyjne w Java EE i Spring Framework

Transkrypt

Bezpieczeństwo aplikacyjne w Java EE i Spring Framework
1
Bezpieczeństwo aplikacyjne w Java EE i Spring
Framework
Agnieszka Brejnak
Instytut Informatyki
Wydział Elektroniki i Technik Informacyjnych
Politechnika Warszawska
Email: [email protected]
Streszczenie—Poniższy artykuł ma na celu przedstawienie
na ogólnym poziomie dwóch platform dla tworzenia aplikacji
korporacyjnych w języku Java: Java Enterprise Edition w
wersji 5 oraz Spring Framework w wersji 2.5. Dodatkowo
autor bardziej szczegółowo omówi i porówna pod względem
kompletności oraz łatwości użycia dostępne mechanizmy zapewnienia bezpieczeństwa w obydwu tych rozwiązaniach.
Zostanie także zaproponowany sposób poprawienia wygody
korzystania z deklaratywnego zabezpieczania aplikacji.
Słowa kluczowe—Java, Java EE, Spring Framework,
Spring Security, Bezpieczeństwo aplikacyjne
A. Historia JEE
Pierwszy standard Javy w wersji korporacyjnej został
opracowany w 1998 roku. Początkowo zawierał tylko
specyfikację komponentów Enterprise Java Beans (EJB)
oraz Servletów. Kolejne wersje - J2EE 1.2, 1.3, 1.4,
aż do JEE 5 (zmiana sposobu wersjonowania) wnosiły
poprawki do poprzednich wersji oraz rozszerzały portfolio
technologii.
B. Opis platformy JEE
I. Wstęp
A
PLIKACJE klasy korporacyjnej charakteryzują się
skomplikowaną logiką biznesową, integracją z systemami spadkowymi a także wysokimi wymaganiami dotyczącymi wydajności, skalowalności oraz bezpieczeństwa.
Zaprojektowanie i stworzenie tak skomplikowanego systemu jest czasochłonne i w efekcie bardzo kosztowne. Z
tego względu projektanci i programiści tak chętnie korzystają z tak zwanych szkieletów aplikacyjnych, które systematyzują pracę nad systemami ułatwiając te czynności,
które powtarzają się w większości projektów. Aktualnie na
rynku informatycznym można wybierać między wieloma
szkieletami dla aplikacji programowanych w języku Java.
Standardem jest Java Enterprise Edition. W ostatnich latach jednak ogromną popularność zdobył Spring Framework
zmniejszając znaczenie oryginalnej specyfikacji firmy Sun
Microsystems.
W pierwszej części artykułu zostanie przedstawiony standard Java EE oraz szkielet aplikacyjny Spring Framework.
Autor pokaże główne problemy JEE oraz różnice funkcjonalne jak i logiczne między tymi platformami. W drugiej
części artykułu omówione zostaną sposóby zapewnienia
bezpieczeństwa aplikacynego w JEE oraz Spring Framework. Następnie autor zapronuje sposób wyeliminowania uciążliwości związanych z deklaratywnym opisem reguł
dostępu do aplikacji.
II. Java EE
Według definicji producenta: ”JEE definiuje standard
tworzenia wielowarstwowych aplikacji opartych na komponentach, oraz opisuje wymagania wobec ich środowiska
wykonania.” [1]. Java EE wykorzystuje dorobek Javy SE
oraz definiuje dodatkowe usługi co ma prowadzić do uproszczenia procesu tworzenia i wdrażania bezpiecznych i
stabilnych rozwiązań biznesowych.
Na jakość i rozległe możliwości Java EE wpływają
przede wszystkim specyfikacje jej technologii składowych.
Głównymi jej częściami są komponenty EJB, servlety,
strony Java Server Pages (JSP), framework Java Server
Faces (JSF), ale również mechanizmy do wydajnej obsługi plików XML (StAX) czy komunikacji z usługami
sieciowymi (JAX-WS). Z wymienionych wyżej technologii
programista może korzystać bezpośrednio. Jednak JEE
definiuje także standard usług, które muszą zostać
udostępnione przez serwer aplikacyjny - transakcyjność,
bezpieczeństwo, obsługa protokołów i inne.
Rys. 1
Technologie JEE
Serwer aplikacyjny jest niezbędnym środowiskiem uruchomieniowym dla aplikacji biznesowej JEE. Dodatkowo,
jak zostało pokazane na rysunku B, kompletnie funkcjonalny serwer musi udostępniać dwa rodzaje kontenerów:
2
Webowy (do obsługi żądań wysyłanych przez protokół
HTTP/HTTPS) oraz EJB (do realizacji logiki biznesowej).
Klientami aplikacji biznesowej mogą być standardowe wolnostojące aplikacje biurkowe Javy, przeglądarki internetowe, inne aplikacje biznesowe oraz usługi sieciowe.
C.2 Java Server Faces
JSF jest to szkielet webowy wspomagający tworzenie
interfejsu użytkownika aplikacji JEE uruchamianych po
stronie serwera. Najczęściej wykorzystuje się go w aplikacjach zgodnych z architekturą MVC rozdzielającą interfejs
graficzny, od warstwy logiki i danych. JSF jest nazywany
technologią wspierającą, gdyż wykorzystuje ona istniejące
mechanizmy (JSP oraz Servlety), aby usprawnić tworzenie
aplikacji. JSF ułatwia:
• nawigację między stronami JSP
• umiędzynarodowianie aplikacji
• walidację formularzy
• obsługę wyjątków
• zarządzanie cyklem życia obiektów
D. Problemy
Mimo iż specyfikacja JEE jest dojrzałym i wciąż rozwijanym standardem cieszy się coraz mniejszą popularnością. Jakie są tego przyczyny? Źródła takich trendów są
zarówno technologiczne jak i marketingowe.
Rys. 2
Architektura aplikacji JEE
Należy mieć świadomość, że JEE nie jest produktem a
jedynie specyfikacją, zestawem API, które zostają dopiero
zaimplementowane przez producentów serwerów aplikacyjnych. Producenci Oracle, IBM czy BEA muszą poddać
swoje rozwiązania zestawowi testów (Java EE 5 Compatibility Test Suite) przygotowanych przez firmę Sun, aby
zostały one uznane za zgodne ze specyfikacją. Oznacza to,
że udostępniają wszystkie usługi w sposób określony przez
dokumentację JEE.
C. Główne technologie JEE
Składowe specyfikacji JEE są bardzo obszerne i autor
mógłby poświęcić każdej z nich osobny artykuł. Ponieważ
nie jest to przedmiotem tego artykułu zostaną przedstawione jedynie dwie istotne elementy JEE.
D.1 Złożoność
Zestaw API wymagany przez Sun wobec producentów
serwerów jest zdecydowanie zbyt obszerny. Nawet dwa
lata nie wystarczyły niektórym wiodącym producentom na
zaimplementowanie całego standardu. Aby rozwiązać ten
problem grupa ekspercka, która planuje wydać kolejną wersję JEE we wrześniu, chce podzielić specyfikację na części i
umożliwić producentom etapowe zdobywanie kompatybilności.
D.2 Brak wsparcia dla testów jednostkowych
W dobie zwinnego (agile) zarządzania projektami programiści dużą wagę przykładają do testów. W podejściu
TDD (Test Driven Development) najpierw powstają testy
jednostkowe, następnie implementowane są klasy. Niestety
JEE nie wspiera testów jednostkowych w żaden sposób.
Można zauważyć, że przez konieczność uruchamiania komponentów biznesowych (ziaren EJB) na serwerach aplikacyjnych, nawet je utrudnia.
D.3 Powolne zmiany
C.1 Enterprise Java Beans
Ziarna EJB są immanetnym i centralnym elementem
specyfikacji JEE. EJB są reużywalnymi komponentami aplikacyjnymi, które realizują logikę biznesową.
Począwszy od wersji 3.0 są zwykłymi klasami Javy
(Plain Old Java Object) dodatkowo opatrzonymi adnotacjami, które umożliwiają rozpoznanie, zarejestrowanie
i zarządzanie nimi przez kontener. Środowiskiem wykonania EJB jest kontener EJB, co umożliwia dostarczenie im zadeklarowanych usług takich jak bezpieczeństwo
i transakcyjność. Ziarna EJB dzielą się na ziarna sesyjne
i sterowane komunikatami. Wyjątkowo nieudana specyfikacja ziaren encyjnych (w wersjach 2.x) została zastąpiona przez zupełnie nowe rozwiązanie utrwalania danych Java Persistence API.
Od początku Java w wersji korporacyjnej z opóźnieniem reagowała na zmiany w dynamicznym i wymagającym środowisku informatyków. Można wymienić Java
Persistence API, jako naśladowcę otwartego frameworku
Hibernate, adnotacje jako kopię XDoclet, czy framework
Java Server Faces wzorowany na Struts. Wstrzeliwanie
zależności (DI) to mechanizm, którego implementacja pojawiła się na przykład w kontenerze Spring IoC wcześniej
niż zostało to uwzględnione w JEE. Te rozwiązania pojawiły się w standardzie JEE na tyle późno, że programiści nie
okazali im dużego zainterosowania i zaufania.
D.4 Zła opinia
Programowanie przy użyciu J2EE 1.4 było uciążliwe,
komponenty EJB nie mogły być implementowane jako
BEZPIECZEńSTWO APLIKACYJNE W JAVA EE I SPRING FRAMEWORK
POJO, utrwalanie danych było żmudne. Przyczyniło się to
do powstania artykułów takich jak ”101 EJB Damnations”
(101 przekleństw EJB) [11]. Pomimo tego, iż Java EE 5
jest zdecydowanie bardziej dopracowana niż jej poprzednia wersja, jednak nie udało się jej zupełnie odmienić złej
opinii programistów.
III. Spring Framework
Trudno jest odnaleźć poprawną, pełną i zrozumiałą
definicję Spring Framework. Jest to związane z tym, że
Spring pełni dwie odległe od siebie funkcje w tworzeniu i
uruchamianiu aplikacji. W swojej książce R. Harropand
zwięźle opisał Springa: ”Spring is a lightweight inversion
of control and aspect-oriented container framework” [6]
Oznacza to, że Spring jest z jednej strony szkieletem aplikacyjnym, wspomagającym proces tworzenia oprogramowania, dostarczający pewnych gotowych mechanizmów, oferujący sprawdzone schematy rozwiązań dotyczących architektury aplikacji i przepływu sterowania. Jest także
kontenerem, czyli środowiskiem uruchumieniowym dla aplikacji.
3
Moduł Core to komponent odpowiadający za udostępnienie funkcje kontenera. Kontener Springowy (często
nazywany kontenerem IoC) jest podobny do kontenera
serwera aplikacyjnego pod względem funkcji jakie spełnia - zarządzanie cyklem życia obiektów, wstrzeliwanie zależności, udostępnienie usług katalogowych, zapewnienie
transakcyności i bezpieczeństwa. Jednak kontener Springa
nie jest tym samym co kontener EJB, gdyż może zostać
uruchomiony z jednej linii kodu źródłowego na zwykłej
maszynie wirtualnej Javy. Z tego względu aplikacje korzystające ze Springa nie potrzebują serwera aplikacyjnego
(ale mogą być uruchamiane także na nich).
A. Historia SF
Spring Framework 1.0 został wydany przez firmę Interface21 (aktualnie SpringSource) w marcu 2004. Główna
idea oraz pierwsze kody źródłowe zostały opublikowane
przez ’ojca Springa’ Roda Johnsona książce jego autorstwa
w 2002 roku. [4]. Aktualnie obowiązuje wersja 2.5.
Rys. 4
Komponenty biznesowe JEE muszą być uruchomione w
kontenerze EJB
B. Opis platformy SF
W przeciwieństwie do JEE Spring nie został zaprojektowany zgodnie z ideą ”wszystko albo nic”. Jego architektura jest modułowa, a każdy komponent jest niezależny od
pozostałych, co oznacza, że do systemu można wykorzystać
tylko część możliwości frameworku, co nie koliduje z innymi
wykorzystywanymi technologiami. Istotne jest, iż Spring
pełniąc rolę szkieletu aplikacyjnego wspomaga tworzenie
aplikacji na każdym poziomie od zarządzania cyklem
życia obiektów, dostęp do danych po programowanie aspektowe.
Rys. 5
Kontener Springa uruchamiane na JVM lub w kontenerze
webowym
C. Główne cechy SF
C.1 Kontener
Rys. 3
Architektura modułowa Spring Framework
Zgodnie z definicją przytoczoną na początku tego rozdziału można stwierdzić, że Spring cechuje się lekkim,
nieinwazyjnym kontenerem (nie wymaga wykorzystania
swoich specyficznych metod, rozszerzania klas czy realizacji interfejsów w kodzie źródłowym aplikacji). Kontener
Springa jest typu Dependency Injection, co oznacza, że w
jego zakresie leży identyfikacja i tworzenie obiektów aplikacji. Obowiązek zarządzania cyklem życia obiektów,
4
ich instancjonowanie, konfigurowanie i ’dekorowanie’ dodatkowymi usługami zostało zdjęte z aplikacji i przekazane
frameworkowi. Czyni to kod prostszym, a powiązania
między obiektami - luźniejszymi.
C.2 Programowanie aspektowe
Dodatkowo umożliwia programowanie aspektowe dzięki
któremu można deklaratywnie zapewnić bezpieczeństwo i
transakcyjność.
architektura modułowa
wstrzeliwanie zależności
wymagany kontener EJB
inwazyjność
adnotacje
TDD
inne technologie
nie
tak(ograniczenia)
tak
tak
tak
nie
nie
tak
tak
nie
nie
tak
tak
tak
TABLE I
Cechy JEE i Spring Framework
C.3 Ułatwienia dostępu do danych
Spring stara się zrealizować swój cel (”ułatwienie tworzenie aplikacji korporacyjnych w Javie” [3]) i dostarcza mechanizmy znacznie upraszczające implementację
warstwy dostępu do danych. Klasycznym przykładem
iustrującym to ułatwienie jest dostęp do bazy danych
poprzez JDBC. Przy podejściu standardowym (programista korzysta jedynie z JDBC) konieczne jest zestawianie połączenia, zamknięcie połączenia, łapanie wyjątków
w razie niepowodzenia, a obsługa wyniku zapytania nie
jest intuicyjna. Spring eliminuje te ’irytacje’ dostarczając
klasę JdbcTemplate, która zwalnia programistę z pisania
zbędnego kodu. Żmudne obowiązku obsługi bazy danych
framework przejmuje i wykonuje w sposób poprawny acz
niewidoczny.
C.4 Wykorzystanie innych technologii
Spring nie ogranicza możliwości wyboru innych technologii i rozwiązań, a nawet dostarcza mechanizmy integracji. Aby osiągnąc pożądany efekt użycie Springa można
połączyć z elementami JEE, Hibernate, TopLink, Struts,
WebWork, Apache CXF...
C.5 Usprawnienia testów
W przeciwieństwie do JEE aplikacje Springowe nie
potrzebują serwera aplikacyjnego jako środowiska uruchomieniowego. Oznacza, to wygodniejsze testowanie jednostkowe, które może być wykonane na dowolnej wirtualnej maszynie Javy. Dodatkowo Spring udostępnia także
pakiety usprawniające pisanie nietrywialnych przypadków
testowych.
IV. Porównanie JEE i Spring
Należy zwrócić uwagę, że kluczową różnicą między JEE
a Spring jest różnica logiczna. Podczas gdy JEE jest
tylko standardem, Spring jest jednocześnie standardem
i implementacją swojego API. Świadomość tej różnicy
jest niezbędna do poprawnego spojrzenie na możliwości
obydwu tych platform.
JEE i Spring Framework współistnieją zgodnie w
środowisku aplikacji korporacyjnych od czterech lat
ponieważ nie są one tym samym. Aktualnie współpraca
między firmami Sun i SpringSource układa się poprawnie
- SpringSource został zaproszony do tworzenia JEE 6
jako członek grupy ekspertów oraz do wygłoszenia kilku
refereratów na największej corocznej konferencji organizowanym przez Sun - Java One 2008. Jeden z nich został
poświęcony bezpieczeństwu aplikacyjnemu.
V. Bezpieczeństwo
Bezpieczeństwo w informatyce może być definiowane
na wielu poziomach. Wśród podstawowych poziomów
wymienia się: ochrone fizycznego dostępu do urządzeń,
zabezpieczenia systemu operacyjnego, sieci komputerowych, baz danych, aplikacji oraz ochronę komputera użytkownika końcowego. Dodatkowo, w korporacjach przybiera na znaczeniu uświadamaianie pracowników
przed socjotechnikami służącymi wyłudzeniu haseł czy
uzyskaniu fizycznego dostępu do maszyn.
VI. Bezpieczeństwo aplikacyjne
Zapewnienie bezpieczeństwa w aplikacji to trudne
zadanie, które spoczywa na programiście. Bezpieczna aplikacja to taka, która nie tylko sama nie stanowi zagrożenia
dla zasobów informacyjnych i sprzętowych, ale również w
swoim zakresie uniemożliwia niepowołany dostęp do nich.
Problemy i zadania dla aplikacji możemy sprowadzić do
listy zagadnień:
• Uwierzytelnianie
czyli weryfikacja tożsamości
użytkownika
• Autoryzacja czyli kontrola dostępu do zasobów przez
uwierzytelnionego użytkownika
• Integralność danych czyli zabezpieczanie danych
przed zamierzoną lub niezamierzoną błędną zmianą
• Niezaprzeczalność
czyli uniemożliwienie zaprzeczenia aktywności użytkownika
• Logowanie aktywności czyli dokładny zapis aktywności użytkownika w systemie
• Wykrywanie aktywności człowieka czyli ochrona
przed użytkowaniem przez maszynę aplikacji przeznaczonej dla człowieka
A. JEE Security i Spring Security
Zarówno Java Enterprise Edition jak i Spring Framework wspierają programistę w tworzeniu systemu bezpieczeństwa dla aplikacji korporacyjnych. Bezpieczeństwo
w JEE jest traktowana jako jedna z usług udostępnianych przez serwer. Spring Security (wcześniej znany jako
Acegi Security) to jeden z projektów należących do Spring
Framework.
BEZPIECZEńSTWO APLIKACYJNE W JAVA EE I SPRING FRAMEWORK
5
A.1 Różnica logiczna
Można przyjąć, że mechanizmy ochrony aplikacji
dostępne dla programisty w Java EE i Spring Security mają
wiele cech wspólnych. Jednak przed zaprezentowaniem
możliwości obydwu tych platform należy zanotować, że
bezpieczeństwo w JEE jest tylko zestawem API, który
ma być zaimplementowany przez serwer aplikacyjny. Oznacza to, że realizacja mechanizmów bezpieczeństwa różnić
się będzie między serwerami różnych producentów. Dlatego nie można powiedzieć, że bezpieczeństwo zapewniane przez JEE jest przenośne - zdarza się bowiem, że
należy ponownie konfigurować ustawienia bezpieczeństwa
przy zmianie serwera.
Spring Security jest specyfikacją, ale jednocześnie dostarcza szeroką gamę implementacji swojego API wystarczającą dla zdecydowanej większości projektów. Dodatkowo
zgodnie z ideą otwartego oprogramowania Spring Security
jest stosunkowo łatwo rozszerzalne i umożliwia dostarczenie własnych implementacji. Jest to przydatne, gdy aplikacja musi zintegrować się z niestandardowymi dla korporacji systemami wymagającymi specyficznych mechanizmów bezpieczeństwa. Takie sytuacje nie zdażają się
zapewne często, ale zostały przewidziane przez projektantów Spring Security. To wszystko oznacza to, że zagwarantowana jest rzeczywista przenośność polityki bezpieczeństwa na poziomie pliku WAR (Web ARchive) lub
EAR (Enterprise ARchive). Jeśli jednak projektantowi zależy na skorzystaniu z rozwiązań dostarczanych przez serwer aplikacyjny, to również ma taką możliwość, w oczywisty sposób wpływa to ujemnie na przenośność.
Różnica logiczna między mechanizmami bezpieczeństwa w
JEE i Spring jest dokładnie taka sama jak między samymi
platformami JEE i Spring.
B. Architektura
JEE definiuje jedynie zestaw API jakie ma zostać
udostępnione przez kontener dla programisty - implementacja może być odmienna dla różnych serwerów aplikacyjnych, z tego względu nie można wspolnej architektury.
W przeciwieństwie, Spring Security jako platforma do
zabezpieczania aplikacji ma jasno sprecyzowaną architekturę i sposób działania.
Opiera się ona na metodach przechwytujących zdarzenia oraz serii filtrów, które
uruchamiane w określonej kolejności zapewniają kolejne
poziomy zabezpieczeń. Wykonanie oraz kolejność wykonania filtrów jest konfigurowalna. Dodatkowo, istnieje możliwość dodania własnych specyficznych filtrów wykonujących niestandardowe działania zabezpieczające.
B.1 Definicja reguł bezpieczeństwa
Reguły bezpieczeństwa w aplikacji obejmują ustalenie
listy ról w systemie, ich uprawnienia oraz zadeklarowanie
akcji zabezpieczających. Ich zdefiniowanie możliwe jest na
trzy sposoby:
• programowe
• deklaratywne, zawyczaj w zewnętrznym pliku XML
• poprzed adnotacje
Rys. 6
Wiele filtrów chroni zabezpieczany zasób
Istnieją wady i zalety każdego z tych podejść. Najrzadziej
stosuje się programowe zabezpieczanie aplikacji - jest ono
najbardziej podatne na błędy i zaniedbania programisty,
a ponadto polityka bezpieczeństwa pozostaje zapisana na
stałe w kodzie aplikacji, co znacznie utrudnia jej modyfikację. Programowe zapewnianie bezpieczeństwa wpływa
także ujemnie na reużywalność kodu.
Adnotacje częściowo rozwiązują ten problem, gdyż nie jest
konieczna modyfikacja ciał klas i metod aby zmienić dla
niej regułę dostępu, wystarczy bowiem tylko zmodyfikować
adnotację.
Rozwiązanie z deklaracją bezpieczeństwa w zewnętrznym
pliku (najczęściej w języku XML) sprawia, że bezpieczeństwo staje się aspektem zupełnie niezależnym od
implementacji logiki. Niestety oznacza to konieczność
stworzenia nowego, zazwyczaj obszernego pliku konfiguracyjnego dla aplikacji. W dalszej części artykułu autor przyjmie właśnie ten sposób definicji polityki bezpieczństwa.
B.2 Obszary zabezpieczeń
W JEE temat bezpieczeństwa jest podzielony na dwa
główne obszary. Pierwsza z nich to zabezpieczenie warstwy
webowej, opisane w specyfikacji servletów i zapewniana
przez kontener webowy. Druga to zabezpieczenia ziaren
EJB. Specyfikacja EJB wskazuje na możliwość deklaratywnego i programowego zabezpieczania wywołań metod
komponentów oraz wyboru sposobu przekazywania kontekstu przy wywołaniach zdalnych.
W przypadku Spring Security bezpieczeństwo jest potraktowane całościowo. Można jednak wyróżnić trzy obszary
aplikacji, które mogą być chronione:
• warstwa webowa - zakres zabezpieczeń porównywalny do warstwy webowej JEE
• warstwa serwisowa - zabezpieczenie wywołania
metod wszystkich używanych obiektów (nie tylko
ziaren EJB jak w przypadku JEE)
6
warstwa obiektów - dodatkowy poziom zabezpieczeń, niedostępny w JEE, umożliwia kontrolowanie
dostępu do instancji obiektu
W przypadku aplikacji Springowej - wszystkie obiekty są
zarządzane przez jeden kontener IoC i można je w całości
zabezpieczać. Aby włączyć metody zabezpieczenia dla aplikacji korzystającej ze szkieletu Spring należy do deskryptora aplikacji (pliku web.xml) dołączyć konfigurację filtrów
przechwytujących żądania użytkowników:
C. Autoryzacja
przez aplikację
X509 - bezpieczne uwierzytelnianie, połączone z
wymianą certyfikatów
Korzystając ze Spring Security oprócz wyżej wymienionych
mechanizmów uwierzytelniania programista może jeszcze
użyć trzech dodatkowych sposobów:
• remember-me - umożliwia zapamiętanie loginu i
hasła użytkownika pomiędzy sesjami (bardzo chętnie
wykorzystywane w korporacyjnych stronach www)
• SSO
uwierzytelnianie
realizowane
jako
przekierowanie użytkownika do centralnej strony
logowania
• anonimowe - umożliwia przypisanie nieuwierzytelnionemu użytkownikowi roli (a co za tym idzie także
uprawnień). Prowadzi to do ujednolicenia zapisu uprawnień dla wszystkich użytkowników.
Aby dokonać uwierzytelnienia należy nie tylko pobrać od
użytkownika jego nazwę i hasło, ale także je zweryfikować.
Lista użytkowników z hasłami może zostać podawna w
dowolny sposób: bezpośrednio w aplikacji, bądź w pliku
(te dwa podejścia są używane w procesie tworzenia oprogramowania i testów) a także w bazie danych, repozytorium LDAP czy systemach obsługujących SSO (te podejścia są najczęściej używane). Możliwe jest również włączenie szyfrowania hasła wybranym algorytmem.
<bean id="channelProcessingFilter"
class="org(.sf.s).securechannel.ChannelProcessingFilt
<property name="channelDecisionManager"
ref="channelDecisionManager"/>
<property name="filterInvocationDefinitionSource">
<sec:filter-invocation-definition-source>
<sec:intercept-url pattern="/secure/.*"
access="REQUIRES_SECURE_CHANNEL"/>
<sec:intercept-url pattern="/login.jsp"
access="REQUIRES_SECURE_CHANNEL"/>
<sec:intercept-url pattern="/**"
access="REQUIRES_INSECURE_CHANNEL"/>
</sec:filter-invocation-definition-source>
</property>
</bean>
•
Autoryzacja, czyli kontrola dostępu, jest możliwa po
uprzednim uwierzytelnieniu użytkownika. W Spring Security jak i JEE autoryzacja jest umożliwia sprawdzenie czy użytkownik posiada wystarczające uprawnienia,
aby zobaczyć żądaną stronę, czy też wykonać wskazaną
metodę z danej klasy. Dodatko w Spring Security można
również autoryzować wyniki działania aplikacji. W Spring
Security decyzję o przyznaniu dostępu podejmuje się w
drodze głosowania - jeśli zarejestrowano kilka mecha<filter>
nizmów sprawdzenia uprawnień, to każdy informuje o swo<filter-name>
jej decyzji. Ostateczna decyzja może być podjęta na kilka
springSecurityFilterChain
sposobów:
</filter-name>
• AffirmativeBased - decyzja pozytywna jeśli choć je<filter-class>
den głos jest pozytywny
org.springframework.web.filter.DelegatingFilterProxy
• ConsensusBased - decyzja jest zgodna z decyzją
</filter-class>
większości głosów
</filter>
• UnanimousBased - decyzja pozytywna wtedy i tylko
<filter-mapping>
wtedy gdy wszystkie głosy są pozytywne
<filter-name>
• custom - reguły rozstrzygania zaimplementowane
springSecurityFilterChain
przez programistę
</filter-name>
<url-pattern>/*</url-pattern>
D. Zabezpieczenie kanału
</filter-mapping>
W przypadku zabezpieczania komunikacji aplikacji z
klientem korzystającym z przeglądarki zarówno Spring
B.3 Uwierzytelnianie
Security jak i JEE pozwalają na wymuszenie protokołu
W specyfikacji JEE określone jest wymaganie wspar- HTTPS. Aby to zapewnić należy w pliku XML opisucia (przez serwery aplikacyjne) dla czterech rodzajów jacym instalację aplikacji zamieścić odpowiednią konfigurację. Tak jak w poprzednich przypadkach platforma
uwierzytelniania:
Spring Security pozwala na większą elastyczność konfigu• basic - podstawowe, obsługiwane przez przeglądarkę
racji i umożliwia ustawienie wymagań dotyczących kanału
• digest - podstawowe z szyfrowaniem hasła
transportu dla poszczególnych stron lub grup stron.
• form-based - formularz logowania przygotowany
•
E. Warstwa serwisowa
Zarówno JEE i Spring Security umożliwiają deklaratywne określenie uprawnień do wywołania metod danej klasy.
W obydwu tych rozwiązaniach zapewnienie bezpieczeństwa
jest zapewnione poprzez definicję odpowiednich aspektów.
W przypadku Spring Security żądania wykonania metod
są przechwytywane a filtry sprawdzają czy użytkownik ma
prawo wykonać daną metodę wybranej klasy.
Dodatkowo Spring Security umożliwia użycie filtrów, które
BEZPIECZEńSTWO APLIKACYJNE W JAVA EE I SPRING FRAMEWORK
Rys. 7
Wymuszenie HTTPS
są uruchamiane po wykonaniu metody - mają one na
celu sprawdzenie czy dany użytkownik (który miał prawo
wykonać daną metodę) ma także dostęp do wyniku działania metody. W szczególności filtr może wyrzucić wyjątek,
bądź zmienić wynik działania metody poprzez usunięcie
z listy wyników obiektów, do których użytkownik nie ma
uprawnień.
F. Ochrona instancji obiektów
Aspekt drobnoziarnistej ochrony obiektów, dotyczącej
konkretnej instancji obiektu, a nie klasy został całkowicie
pominięty w specyfikacji JEE - takie zabezpieczenie można
osiągnąć jedynie programowo. Deklaratywne określenie takich uprawnień jest możliwe w Spring Security. Każda instancja obiektu może mieć swoją własną listę uprawnień tzw ACL (Access Control List), określającą uprawnienia
dostępu do tej instancji i wywołania jej metod. Dodatkowo Spring Security umożliwia sprawdzenie, aby dany
użytkownik ma uprawnienia do wyników działania metod.
G. Dodatkowe możliwości
W porównaniu do bezpieczeństwa w JEE, Spring Security umożliwia dodatkowo kontrolę łącznej ilości sesji
danego użytkownika, wsparcie dla hierarchicznych ról
użytkownika, grup oraz integrację z mechanizmem wykrywania ludzkiej aktywności: JCaptcha.
H. Porównanie i identyfikacja problemów
Z punktu widzenia zapewnienia podstawowego bezpieczeństwa funkcjonalność JEE jak i Spring Security nie
różnią się istotnie. Jednak to projekt firmy SpringSource
daje większe możliwości zdefiniowanie dokładniejszych zasad dostępu do aplikacji. Większa różnorodność mechanizmów uwierzytelniania, wsparcie dla hierarchicznych ról,
kontrola dostępu do instancji obiektu czynią Spring Security rozwiązaniem bardziej kompleksowym i gwarantującym większą elastyczność.
Dodatkowo definiując zabezpieczenia na poziomie JEE
programista nie ma pewności jak zostaną one zaimplementowane w serwerze aplikacyjnym, nie ma nad nimi pełnej
kontroli ani możliwości dodatkowej ich konfiguracji. Dzięki
zapewnieniu usług bezpieczeństwa przez kontener Springa,
a nie kontener serwera aplikacyjnego systemy korzystające z frameworku Spring są całkowicie przenośne między
różnymi serwerami i ustawienia polityki bezpieczeństwa
mogą pozostać niezmienione.
7
Łatwo widać, że bezpieczeństwo w aplikacjach korporacyjncych jest głównie konfigurowane a nie programowane.
Chcąc zapewnić złożone reguły bezpieczeństwa należy
je opisać w zewnętrznych plikach XML. W przypadku
prostych, standardowych reguł bezpieczeństwa opis nie jest
skomplikowany - w przypadku Spring Security 2.0 powstało nawet udogodnieniem, które przyjmując pewne założenia generuje podstawowe reguły na podstawie znikomej
ilości kodu XML. Jednak dla bardziej złożonych i niestandardowych mechanizmów napisanie i utrzymanie
spójności w tych plikach jest niestety czasochłonne i
nużące. To jest cena jaką płaci się za odseparowanie logiki
biznesowej aplikacji od jej polityki bezpieczeństwa.
VII. Rozszerzenie dla Eclipse
Nie da się przecenić korzyści płynących z rozdzielenia
logiki biznesowej aplikacji od jej wymagań dotyczących
bezpieczeństwa. Spring Security umożliwia zadeklarowanie
reguł bezpieczeństwa na dużym poziomie szczegółowości jednak nie jest to rozwiązanie idealne. Głównym problemem przed którym staje programista jest stworzenie, a
następnie utrzymanie zewnętrznego pliku XML.
Usprawnienie deklarowanie reguł bezpieczeństwa dla aplikacji korporacyjnych napisanych w Javie przy użyciu Spring Security można osiągnąć poprzez zautomatyzowanie procesu tworzenia potrzebnych wpisów konfiguracyjnych dla aplikacji. Autor proponuje stworzenie rozszerzenia graficznego dla cieszącego się dużą popularnością środowiska aplikacyjnego Eclipse IDE, w którym programista mógłby za pomocą interfejsu graficznego włączyć
i skonfigurować obsługę filtrów przechwytujących, a także
określić wymagania dotyczące zabezpieczenia apikacji na
wszystkich poziomach wspieranych przez Spring Security.
Wtyczka będzie integrować się z istniejącym już rozszerzeniem IDE, będzie umożliwiała rozpoznawianie obiektów aplikacji ich elementów składowych i zdefiniowanych
metod. Rozszerzenie to będzie dostępna na każdym etapie
procesu tworzenia systemu, w szczególności umożliwi dodanie reguł bezpieczeństwa dla gotowej aplikacji, a także
tej będącej w fazie implementacji. Eclipse IDE jest ot-
Rys. 8
Eclipse i jego budowa
wartą i rozszerzalną platformą wspieraną przez firmę IBM.
Z wyjątkiem niewielkiego jądra aplikacji, cała funkcjonalność jest zrealizowana poprzez wtyczki. Taka architektura
gwarantuje jednolity sposób rozszerzania aplikacji oraz
8
standardowy dostęp do komponentów aplikacji takich jak
interfejs graficzny, pomoc, debugger i innych zasobów.
VIII. Podsumowanie
W pracy przedstawiono standard Java Enterprise Edition i szkielet aplikacyjny Spring Framework, ich możliwości i niedociągnięcia, a także wyjaśniono główną logiczną
róźnicę między nimi. Omówione zostały także omówione
sposoby zapewnienia bezpieczeństwa dla aplikacji korporacyjnych dostępne w obydwu tych rozwiązaniach na podstawie specyfikacji zabezpieczeń servletów, komponentów
EJB oraz projektu Spring Security. Autor ocenił możliwości oraz wygodę użycia obydwu mechanizmów. W ostatniej częsci dokumentu zostało zaproponowane i opisane
rozwiąznie usprawniające definiowanie i zarządzanie reguł
bezpieczeństwa dla Spring Security.
Literatura
[1] Shannon, B.: Java EE Specification, Sun Microsystems, 2006
[2] Mukhar, K., Zelenak, C.: Java EE 5 from Novice to Proffesional,
Apress, 2006
[3] Walls, C., Breidenbach, R.: Spring in Action, Manning Publications Co., 2008
[4] Johnson, R. et al.: Expert one-on-one J2EE Design and Development, Wrox, 2002
[5] Johnson, R. et al.: Professional Java Development with the
Spring Framework, John Wiley and Sons, 2005
[6] Harropand, R., Machacek, J.: Pro Spring, Apress, 2005
[7] Liu, X.: From Java EE security to Acegi, The right way to protect
your Web applications, JavaWorld.com, 2007
[8] Steel, C., Nagappan, R., Lai, R.: Core Security Patterns: Best
Practices and Strategies for J2EE, Web Services, and Identity
Management, Prentice Hall, 2005
[9] Pistoia,M., Nagaratnam, M., Koved, L., Nadalin, A.: Enterprise
Java Security: Building Secure J2EE Applications, Addison Wesley, 2004
[10] Alex, B.: Spring Security: Reference Documentation 2.0.x,
SpringSource, 2007
[11] Sharp, R.:
EJBs 101 Damnations (Online) Available:
http://www.softwarereality.com/programming/ejb/index.jsp,
2002