IPRO - PC Magazine Romania, Decembrie 2003
SOLUȚII PENTRU PROGRAMATORII ȘI DESIGNERII WEB
Tehnologia Java Servlets: Sesiuni. Managementul sesiunilor
Mircea Scărlătescu
Vorbeam în numerele trecute despre tehnologia Java Servlets, mai exact desprepreluarea
datelor de la utilizatori, și despre cum introducem datele necesare într-o bază
de date, cu ajutorul JDBC. Aceste operații sunt întâlnite în cele mai multe
dintre aplicațiile web de azi.
Pentru dezvoltatorii acestor sisteme însă mai există un aspect de care trebuie
să țină cont și care nu de puține ori implică un volum însemnat de muncă: gândirea
unei metode de securizare a aplicațiilor este una dintre cele mai importante
etape în proiectarea aplicațiilor web, având în vedere multitudinea atacurilor
ce se înregistrează asupra multor situri și în special asupra celor care pot
oferi acces la informații importante din punct de vedere comercial.
Securitatea în domeniul informaticii cuprinde atât securitatea la nivelul datelor,
și anume protejarea informațiilor care nu trebuie să fie accesibile decât utilizatorilor
autorizați. Aici includem de la mesajele poștei electronice și până la parole,
date de identificare într-o companie, sau alte informații de acest gen. Din
punct de vedere al aplicației, se dorește protejarea resurselor hardware ale
sistemului, prin blocarea atacurilor de tip DoS și nu numai, pentru a preveni
blocarea, sau - și mai rău - distrugerea sistemului, dar și folosirea acestuia
în scopul de a ataca alte servere.
Vom discuta în cele ce urmează despre protejarea datelor "sensibile"
pentru o aplicație web. Cu toții știm că la sistemele gratuite (sau plătite)
de poștă electronică prin interfețe web (www.go.ro
www.email.ro www.mymail.ro
și putem avea zeci - dacă nu sute - de exemple) accesul la casuța poștală se
face cu un utilizator și o parolă. La fel, la conectarea pe un site care conține
și o secțiune de tip "My" (vezi my.yahoo.com), adică o secțiune personalizată
în funcție de cerințele și preferințele utlizatorului, accesul este și el condiționat
de o parolă.
Dar ce se intâmplă de fapt în spatele acestei parole? După introducerea acesteia,
se compară parola setată într-o baza de date de obicei pentru utilizator cu
string-ul introdus acum pe site.
În cazul în care parola este greșită, de obicei se afișează un mesaj de avertizare
asupra greșelilor ce au apărut, și se cere reintroducerea parolei. Un sfat ce
ține de securizarea aplicațiilor este că dacă un utilizator a introdus de mai
mult de 3 ori consecutiv parola greșită, să nu mai verifice parola cu cea din
baza de date. Se realizează astfel o metodă de a bloca programele care încearcă
să genereze parole în mod aleator, programe folosite pe scară largă de hackeri.
De cele mai multe ori însă parola va fi corectă, deci userul va putea să acceseze
aplicația; aici intră în joc sesiunile, o metodă modernă de a păstra informații
despre utilizarea aplicației. Într-o sesiune se vor reține ID-ul unui user,
numele lui, IP-ul de unde se accesează aplicația și alte informații. Stocarea
unei variabile într-o sesiune, poate fi echivalată cu setarea unei variabile
globale pentru aplicație, ce va fi "vazută" de către paginile aplicației.
Perioada de viață a acestei sesiuni depinde atât de setările serverului dar
și de cele ale aplicației. Se poate seta ca o sesiune să expire după o perioadă
de timp, când se închide browserul utilizatorului, când utilizatorul se deloghează,
etc.
E important ca datele ce se stochează pe sesiune să nu fie mai multe decât
este absolut necesar. Acest lucru contează din două puncte de vedere. Primul
ține de cantitatea de date ce se stochează în memorie, și este evident că mai
multe date pe sesiune înseamnă mai mult spațiu necesar pentru memorare. Și dacă
la o singură sesiune nu pare să conteze prea mult, ținând cont că pentru fiecare
utilizator se generează câte o sesiune, dimensiunile deja încep să conteze!
Al doilea aspect care trebuie luat în calcul este securitatea; orice programator
trebuie să-și pună întrebarea: ce se va întâmpla dacă datele dintr-o sesiune
sunt într-un anumit fel preluate de un utlizator neautorizată. Nu vom face aici
un curs de "hackuire" a sesiunilor, dar trebuie spus că se poate.
Astfel pe o sesiune nu trebuie să fie stocate date de genul parolelor la baza
de date,
IP-uri către diferite servere, sau porturi de acces. De cele mai multe ori,
o variabilă care să rețină un ID al utilizatorului este suficientă pentru a
identifica un utilizator, și a efectua eventuale operații de customizare necesare
pentru aplicație.
Să facem acum o trecere în revistă asupra implementării mecanismelor sesiunilor
în JavaServlets. Sesiunile sunt reprezentate de către obiectul HttpSession care
poate fi accesat prin intermediul metodei getSession; metoda returnează sesiunea
curentă pentru client sau realizează inițializarea unei sesiuni pentru clientul
curent, dacă acesta nu are definită încă o sesiune. Odată initializată o sesiune,
ne interesează să putem defini și apela variabile pe acestă sesiune. Metoda
getAttribute este cea responsabilă de a aduce un obiect din sesiune și de a
face acest obiect disponibil pentru prelucrări în cadrul Servletului. Iată un
exemplu de utilizare a acestei metode.
public class ExempluServlet
extends HttpServlet {
public void doGet (HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
HttpSession sesiune=
request.getSession();
Integer ID=(Integer)
sesiune.getAttribute("ID");
…
}
În exemplul de mai sus, servletul nostru aplează o sesiune unde este stocată
o variabilă care are numele ID și o copiază în variabilă cu același nume a servletului.
Un alt exemplu care trebuie să fie reținut este acela de a seta o variabilă
pe sesiune. Iată răspunsul la această întrebare:
public class ExempluServlet
extends HttpServlet {
public void doGet
(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
HttpSession sesiune=request.
getSession();
Integer ID=(Integer)sesiune.getAttribute("ID");
Integer copy_ID=new Integer(ID.intValue()+1);
//o noua valoare creata din
// valoare din sesiune, incrementata
Sesiune.setAtribute("copy_ID", copy_ID);
//setez o noua variabila pe sesiune
}
Să nu uităm că dacă dorim să actualizăm o variabilă din sesiune modalitatea
este să copiem această variabilă în servlet-ul nostru, așa cum am exemplificat
mai sus, și apoi să o rescriem în sesiune. Altfel, sesiunea va rămâne cu valoarea
veche, neactualizată.
Observăm ușurință cu care sunt realizate "înregistrările" în sesiune,
spre deosebire de alte limbaje de scripting, (mai vechi) în care lucrul cu sesiuni
era o mare problemă, și de multe ori făcea munca de dezvoltator web o durere
de cap.
Prezentăm în continuare și o serie de metode care pot fi folositoare în lucrul
cu sesiuni:
- getId. Această metodă este cea care returnează ID-ul unic care este generat
pentru o sesiune. Este o metodă folositoare atunci când se dorește implementarea
unei politici de securitate avansate; (nu intrăm în detalii, dar trebuie spus
că ID-ul unei sesiuni poate fi folosit în realizarea și întreținerea unor
jurnale de logare, etc.)
- isNew. Returnează true sau false (1 sau 0 logic), testând dacă browserul
nu a ´văzut´ până acum sesiunea (1 dacă sesiunea este nouă, 0
dacă nu).
- getCreationTime Este o metodă ce returnează perioada (în milisecunde) de
când a fost creată sesiunea. De remarcat că atunci când se dorește o afișare
a acestei date, valoarea returnată poate să fie folosită în construcția unui
obiect de tip Date, care va returna stringuri cu această dată sub un format
mult mai ușor inteligibil.
- getLastAccessedTime. Returnează, la fel ca la metoda anterioară, în milisecunde,
momentul ultimei accesări a sesiunii de către client.
- getMaxInactiveInterval. Returnează perioada de timp (în secunde de data
aceasta) după care sesiunea ar trebui să ´expire´ adică datele
încapsulate pe sesiune să fie șterse, iar sesiunea distrusă. O valoare negativă
înseamnă că sesiunea (teoretic) nu expiră niciodată
Pentru ca de multe ori dorim ca datele din sesiune să fie distruse (de exemplu,
la delogarea unui utilizator), trebuie să apelăm metoda
session.invalidate();
În general, este bine să determinăm în cadrul aplicației atunci când sesiunea
nu mai este necesară și să o distrugem. Sesiunile care sunt lasate neînchise
ocupă atât spațiu în memorie fără scop, dar sunt și o potențială problemă din
punctul de vedere al securității.
Să mai spunem în încheiere că lucrul cu sesiuni este una din cele mai importante
componente ale programării aplicațiilor web, din toate punctele de vedere, începând
cu securitatea și terminând cu aspectul siturilor web, care prin identificarea
clienților poate să fie mult mai atractiv, și customizat după preferințe. Posibilitățile
pe care le prezintă pentru comerțul electronic, sau plata online fac internetul
mult mai folositor pentru orice utilizator în ziua de azi, iar sesiunile nu
sunt străine de aceste domenii.
Pentru detalii despre tehnologia Servlets, inclusiv clasele legate de lucrul
cu sesiuni vă propunem doua legături:
http://java.sun.com/products/servlet
http://www.jcp.org/aboutJava/
communityprocess/final/jsr053/index.html
|