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
|