You are on page 1of 51

VISOKA ŠKOLA ZA SAVREMENO POSLOVANJE,

INFORMACIONE TEHNOLOGIJE I TRŽIŠNE


KOMUNIKACIJE „INTERNACIONALNA POSLOVNO-
INFORMACIONA AKADEMIJA“ TUZLA

Informatika i računarstvo

Adin Bešlagić

SIGURNOSNI ASPEKTI RAZVOJA REST API-a

Završni rad

Tuzla, maj 2023.


VISOKA ŠKOLA ZA SAVREMENO POSLOVANJE,
INFORMACIONE TEHNOLOGIJE I TRŽIŠNE
KOMUNIKACIJE „INTERNACIONALNA POSLOVNO-
INFORMACIONA AKADEMIJA“ TUZLA

Informatika i računarstvo

Završni rad

SIGURNOSNI ASPEKTI RAZVOJA REST API-a

Mentor: Student:

mr.sc. Benjamin Suljić dipl.inž.el. Adin Bešlagić

Broj indeksa:

I-0403/18
SAŽETAK

U ovom radu opisane su osnove sigurnosne mjere koje se kao preduslovi zaštite, ali
i kao dobra praksa preduzimaju u razvoju web okruženja koristeći se REST API-em.
Navedeni su osnovni problemi s kojima se korisnici web aplikacija susreću i tehnikama koje
se koriste u prevazilaženju istih. Navedena su i objašnjena moguća mjesta napada na
elemente web aplikacija, te opisana najbolja praksa kako programeri mogu i trebaju osigurati
da privatni dio aplikacije bude zaštićen. Na temelju web aplikacije kao praktičnog dijela rada
i metoda etičnog hakovanja prikazane su ranjivosti jednog takvog sistema i objašnjeno je
kako aplikaciju zaštititi od potencijalnih rizika. Praktični dio završnog rada je web aplikacija
koja koristi sve temeljne preporuke zaštite i sigurnosti.

Ključne riječi: REST, API, Web, Aplikacija, Spring, Boot, Security.


SADRŽAJ

1. UVOD ........................................................................................................................................ 1
2. JAVA.......................................................................................................................................... 2
3. MAVEN ..................................................................................................................................... 4
4. SPRING...................................................................................................................................... 6
4.1. Spring Initializr .................................................................................................................. 6
4.2. Integrisano razvojno okruženje (IDE) ................................................................................ 8
5. REST API................................................................................................................................... 9
5.1. REST .................................................................................................................................. 9
5.2. HTTP .................................................................................................................................. 9
5.3. API ................................................................................................................................... 10
6. IZRADA REST API-a ............................................................................................................. 11
6.1. Klasa Student ................................................................................................................... 11
6.2. REST Controller............................................................................................................... 11
7. POMOĆNE BIBLIOTEKE ...................................................................................................... 15
7.1. Spring WEB ..................................................................................................................... 15
7.2. Spring DATA JPA ........................................................................................................... 16
7.3. Lombok ............................................................................................................................ 17
8. SPRING SECURITY ............................................................................................................... 18
9. AUTENTIFIKACIJA ............................................................................................................... 21
10. ULOGE I DOZVOLE .......................................................................................................... 27
11. CSRF .................................................................................................................................... 32
12. SESIJE I KOLAČIĆI ........................................................................................................... 34
12.1. O kolačićima ................................................................................................................ 36
12.2. O sesijama .................................................................................................................... 38
13. POVEZIVANJE SA BAZAMA PODATAKA .................................................................... 40
ZAKLJUČAK .................................................................................................................................. 43
LITERATURA ................................................................................................................................. 44
POPIS SKRAĆENICA .................................................................................................................... 46
PRILOZI .......................................................................................................................................... 47
1. UVOD

Cyber sigurnost je polje koje se brzo razvija i postaje sve važnije kako se naši životi
sve više oslanjaju na tehnologiju. Od zaštite osjetljivih ličnih i finansijskih informacija do
osiguravanja integriteta kritične infrastrukture, cyber sigurnost igra vitalnu ulogu u
održavanju lične sigurnosti i sigurnosti cjelokupnog društva, stoga sa sigurnošću možemo
reći da je cyber sigurnost jedno od najvažnijih pitanja današnjice.

Uprkos svim naporima da se obezbijedi visok stepen sigurnosti korisnika i njihovih


podataka vrlo često dolazi do curenja podataka, nesigurne autentifikacije, loše kontrole
pristupa, SQL(Structured Querry Language, standardni jezik za rad sa bazama) Injection,
XEE(XML External Entity) i DDOS(Distributed Denial of Service) napada. Dio
odgovornosti za zadovoljavanje aktuelnih sigurnosnih standarda zasigurno preuzimaju i
programeri. Kako bi spriječili već poznate probleme ranjivosti jednog software-a, te time
potencijalne rizike sveli na minimum potrebno je dobro poznavati osnove sigurnosti jednog
takvog projekta.

Ovim radom u glavni fokus će biti stavljena izrada sigurne web aplikacije u Java
programskom jeziku uz pomoć „okvira za rad“ (u daljnjem tekstu kao eng. framework)
Spring i njegove biblioteke Spring Security.

1
2. JAVA

Java je popularan programski jezik koji se široko primjenjuje više od dvije decenije.
Poznat je po svojoj jednostavnosti, objektno orijentisanom dizajnu i portabilnosti, što ga čini
svestranim i široko prihvaćenim jezikom za izradu velikog broja aplikacija.

Jedna od ključnih karakteristika Jave je njena mogućnost pokretanja istog koda na


više različitih uređaja, što znači da se Java kod može prevesti u srednji oblik koji se zove
byte-code koji se može pokrenuti na bilo kojem uređaju koji ima instaliranu Java virtuelnu
mašinu (JVM). Ovo čini Javu posebno pogodnom za pravljenje aplikacija koje treba da rade
na različitim platformama, uključujući Windows, macOS, Linux, Android...

Pored svoje portabilnosti, Java je poznata i po tome da je objektno orijentisan


programski jezik, što znači da se zasniva na konceptu "objekata" koji predstavljaju entitete
iz stvarnog sveta i njihova svojstva i ponašanja. Ovo omogućava programerima da izgrade
modularniji i višekratno upotrebljiv kod, što čini proces razvoja efikasnijim i održivijim.

Java je statički tipiziran jezik, što znači da varijable moraju biti deklarirane sa
određenim tipom podataka prije nego što se mogu koristiti. Ovo pomaže u sprečavanju
grešaka i poboljšanju kvaliteta koda osiguravajući da se varijable koriste dosljedno u cijelom
programu.

Postoje mnoge biblioteke i programski okviri dostupni za Javu koji programerima


olakšavaju izgradnju širokog spektra aplikacija, od web aplikacija i mobilnih aplikacija do
analitike velikih podataka i mašinskog učenja. Neki popularni Java okviri uključuju Spring,
Hibernate i Apache Hadoop.

Jedna od prednosti Jave je njena snažna podrška za multi-threading, koja omogućava


da se više procesa izvršava istovremeno unutar jednog programa. Ovo može biti korisno za
pravljenje aplikacija koje treba da izvode više zadataka istovremeno, kao što je web server
koji obrađuje više zahtjeva odjednom.

Pored svojih osnovnih karakteristika, Java takođe ima bogat skup standardnih
biblioteka koje pružaju širok spektar funkcionalnosti, uključujući ulaz/izlaz, umrežavanje i
manipulaciju podacima. Ove biblioteke olakšavaju programerima da prave aplikacije bez
potrebe za pisanjem koda niskog nivoa.

2
Od svog prvog pojavljivanja 1995. godine Java je pretrpila nekoliko velikih izmjena
kroz verzije, gdje je svaka od njih donijela nove funkcionalnosti i unaprijeđenja, poput novih
sintaksičkih pravila, unaprijeđenih performansi, proširenja fukcionalnosti, API-a
(„Application Programming Interfaces“) i još mnogo toga. Trenutna stabilna vezija je verzija
Java 17, izašla u septembru 2021. 1

Java je moćan i široko korišćen programski jezik koji je poznat po svojoj


jednostavnosti, objektno orijentisanom dizajnu i prenosivosti. Njegova svestranost i
dostupnost niza biblioteka i okvira čine ga popularnim izborom za izgradnju raznih
aplikacija. Snažna podrška za multi-threading i bogat skup standardnih biblioteka čine ga
moćnim alatom za izgradnju efikasnih i skalabilnih aplikacija i vrlo često su razlog zašto se
aplikacije i poput ove čija će izrada biti opisana u ovom radu pišu upravo u Javi.

1
“Java SE, JDK 17 Documentation”, Oracle Help center, https://docs.oracle.com/en/java/javase/17/,
(pristupljeno 18.12.2022.)

3
3. MAVEN

Maven je alat za automatizaciju izrade aplikacija koji se prvenstveno koristi za Java


projekte. 2
Dizajniran je tako da programerima olakša izgradnju i upravljanje projektima
zasnovanim na Javi, uključujući izgradnju, testiranje i implementaciju aplikacija. Maven je
zasnovan na konceptu "projektni objektni model" (POM), koji je XML datoteka koja sadrži
informacije o projektu, uključujući biblioteke (dependencies), konfiguraciju izgradnje i još
mnogo toga.

Jedna od ključnih prednosti Mavena je njegova sposobnost upravljanja eksternim


bibliotekama (dependencies) koje se nalaze tu kao i druge komponente koje su projektu
potrebne da bi se izgradio i pokrenuo. Maven može automatski preuzeti i upravljati ovim
bibliotekama, osiguravajući da se koristi ispravna verzija i da su sve biblioteke dostupne
kada je potrebno. Ovo programerima može uštedjeti vrijeme i trud eliminirajući potrebu za
ručnim upravljanjem biblioteka.

Još jedna ključna karakteristika Mavena je njegova podrška za širok spektar faza
izgradnje, kao što su kompajliranje, testiranje, pakovanje i implementacija. Maven može
automatski pokrenuti ove faze ispravnim redoslijedom, omogućavajući programerima da
izgrade i implementiraju svoje aplikacije pomoću jedne naredbe. Ovo proces razvoja čini
efikasnijim i dosljednijim.

Pored svojih osnovnih mogućnosti automatizacije izgradnje, Maven također nudi


brojne dodatke koji omogućavaju programerima da prošire njegovu funkcionalnost. Na
primjer, dodatak Maven Surefire može se koristiti za pokretanje jediničnih testova. Dobar
primjer je i dodatak Maven Shade koji se koristi za kreiranje izvršne JAR datoteke jednog
projekta. Postoje stotine dostupnih dodataka, što programerima olakšava prilagođavanje
Mavena kako bi zadovoljio njihove specifične potrebe i proces razvoja učinio što
efikasnijim.

Maven je također dizajniran da bude vrlo prilagodljiv i proširiv. Programeri mogu


prilagoditi proces izgradnje dodavanjem vlastitih dodataka ili korištenjem svojstava i profila
za fino podešavanje konfiguracije izgradnje. Ovo omogućava programerima da prilagode
Maven tako da odgovara specifičnim potrebama njihovog projekta.

2
“Welcome to Maven”, Apache Maven Project, https://maven.apache.org/, (pristupljeno 19.12.2022)

4
Sve u svemu, Maven je vrlo moćan i široko korišten alat za automatizaciju izgradnje
koji može značajno pojednostaviti proces razvoja za projekte pisane u Javi. Njegova podrška
za biblioteke, faze izrade i dodatke, kao i njegova konfigurabilnost i proširivost, čine ga
osnovnim alatom za mnoge Java programere, pa će tako Maven i u ovom projektu biti glavni
alat za izgradju.

5
4. SPRING

Spring je popularan Java framework za izgradnju aplikacija. Pruža niz funkcija i


komponenti koje programerima olakšavaju izradu i implementaciju visokokvalitetnih
aplikacija.

Jedna od ključnih karakteristika Springa je njegova podrška za dependency injection


3
, što je design pattern4 koji omogućava da komponente budu labavo povezane, što olakšava
testiranje i održavanje aplikacije. Spring pruža brojne mehanizme za dependency injection
uključujući i već spomenute XML konfiguracije i Java konfiguraciju. Ovo omogućava
programerima da odaberu pristup koji najbolje odgovara njihovim potrebama.

Još jedan važan aspekt Spring-a je njegova podrška za aspektno orijentisano


programiranje (AOP), što programerima daje i opciju da modulariziraju cjelokupne
probleme, kao što su logovanje i sigurnost. Ovo može učiniti aplikaciju modularnijom i
lakšom za održavanje odvajanjem ovih funkcionalnosti od glavne poslovne logike.

Uz svoje osnovne karakteristike, Spring nudi niz modula koji podržavaju širok
spektar funkcionalnosti, uključujući web razvoj, pristup podacima i razmjenu poruka. Na
primjer, Spring Web MVC modul pruža framework za web aplikacija, dok Spring Data
modul pojednostavljuje proces rada sa bazama podataka. Ovi moduli se mogu koristiti
pojedinačno ili u kombinaciji za izgradnju aplikacija širokog spektra funkcionalnosti.

Spring je takođe dizajniran da bude fleksibilan i nadogradiv, sa velikom i aktivnom


zajednicom programera i korisnika. To znači da programeri mogu da iskoriste prednosti
širokog spektra biblioteka i alata treće strane koji su izgrađeni na osnovu Spring-a, kao i da
doprinesu sopstvenim poboljšanjima i proširenjima framework-a.

4.1. Spring Initializr

Spring Initializr5 je web alat koji omogućava programerima da brzo kreiraju novi
Spring Boot projekat.

3
“Dependency Injection”, Oravle Java documentation, https://docs.oracle.com/javaee/dependency-injection ,
(pristupljeno 20.12.2022)
4
Niko Schwarz, Mircea Lungu, Oscar Nierstrasz, “Seuss: Decoupling responsibilities from static methods for
fine-grained configurability”, Journal of Object Technology, Volume 11, no. 1 (April 2012), p. 2
5
Spring Initializr tool, https://start.spring.io/, (pristupljeno 20.12.2022)

6
Korištenje Spring Initializr-a je veoma jednostavno. Prvo, programeri biraju tip projekta koji
žele da kreiraju, kao što je Maven ili Gradle projekat, te biraju verziju Spring Boot-a koju
žele da koriste. Zatim mogu odabrati biblioteke koje žele uključiti u projekt, kao što su Web
MVC, JPA data, Security i druge. Spring Initializr će zatim generisati osnovnu strukturu
projekta i konfiguraciju na osnovu ovih izbora, omogućavajući programerima da odmah
počnu da rade na svojoj aplikaciji.

Slika 1. Izgled stranice Spring Initializr (izvor: https://start.spring.io/, pristupljeno 20.12.2022.)

Spring Initializr također nudi niz naprednih opcija koje omogućavaju programerima
da detaljnije prilagode svoj projekat. Na primjer, jezik koji žele koristiti, Java, Groovy ili
Kotlin, odabrati tip pakovanja projekta koji žele koristiti, JAR ili WAR. Također je moguće
odrediti naziv i lokaciju projekta, kao i sva dodatna svojstva ili opcije konfiguracije koje se
mogu uključiti. Nakon svih postavki i podešavanja koje programer može izvršiti na ovoj
stranici i odluči generisati svoj Spring boot projekat, pokreće preuzimanje demo.zip
dokumenta koji će sadržavati „hello world“ (hello world je naziv za početni projekat koji još
nema nikakvu specifičnu funkcionalnost osim da programeru da do znanja da je program
pokrenut i uspješno izvršen. Obično izvršava ispis “Hello World” u konzoli.) projekat sa
traženom konfiguracijom.Ovaj projekat se otvara u nekom od razvojnih okruženja (IDE), a
u izradi ovog projekta korišten je JetBrains-ov IntelliJ IDEA6.

6
IntelliJ IDEA, Java and Kotlin IDE, https://www.jetbrains.com/idea/, (pristupljeno 12.12.2022)

7
4.2. Integrisano razvojno okruženje (IDE)

Uz neprevaziđen kvalitet opcije auto-complete, jednostavnog i vizualno


primamljivog izgleda IntelliJ IDEA je vjerovatno najmoćniji IDE za Java projekte. Nudi
bogatu paletu alata za razvoj i testiranje, uključujući integrisani sisitem za upravljanje
projektima, debugger, analizu koda i testiranje performansi. Također se može koristiti za
razvoj mobilnih aplikacija, web aplikacija i desktop aplikacija. Pored Jave, ima podršku i za
Kotlin, Scala-u , Groovy, Python i mnoge druge.

Slika 2. Struktura projekta generisanog pomoću Spring Initializr web alata prikazana u IntelliJ IDEA
razvojnom okruženju (izvor: autor rada)

8
5. REST API

5.1. REST

Representational State Transfer (REST) je model za izgradnju web servisa koji je


dizajniran da bude skalabilan, fleksibilan i jednostavan za korištenje. REST 7se zasniva na
skupu principa koji definišu kako bi web servisi trebali biti dizajnirani, uključujući korištenje
HTTP-a kao osnovnog protokola i korištenje jedinstvenog interfejsa za komunikaciju
između klijenata i servera.

5.2. HTTP

Jedna od ključnih prednosti REST-a je njegova upotreba HTTP-a kao osnovnog


protokola. HTTP 8je široko korišten i dobro shvaćen protokol koji podržavaju gotovo svi
web pretraživači i serveri. To znači da se REST uslugama može pristupiti pomoću
standardnih HTTP klijentskih biblioteka, što programerima olakšava izradu aplikacija koje
koriste REST.

HTTP je stateless protokol, što znači da je svaki zahtjev neovisan o bilo kojem
drugom zahtjevu i što je vrlo bitno u razvoju aplikacije čiji će se razvoj pratiti kroz ovaj rad.
Ovo omogućava skalabilnost i fleksibilnost, jer održavanje veze ili stanja između zahtjeva
nije potrebno.

Drugi ključni aspekt REST-a je njegova upotreba uniformnog interfejsa za


komunikaciju između klijenata i servera. To znači da su REST servisi dizajnirani da im se
pristupa korištenjem skupa standardnih HTTP metoda, GET, POST, PUT i DELETE. Ove
metode se koriste za izvođenje različitih tipova operacija, kao što su dohvaćanje podataka,
kreiranje novih resursa, ažuriranje postojećih resursa i brisanje resursa.

REST uslugama se obično pristupa pomoću HTTP zahtjeva, pri čemu klijent šalje
zahtjev serveru, a server vraća odgovor. Odgovor može sadržavati podatke u više različitih
formata, kao što su XML, JSON ili HTML, ovisno o potrebama klijenta.

7
“What is REST”, Restful API, https://restfulapi.net/, (pristupljeno 21.2.2023)
8
“What is HTTP”, Cloudflare, https://www.cloudflare.com/learning/ddos/glossary/hypertext-transfer-
protocol-http/, (pristupljeno 21.2.2023)

9
5.3. API

API 9(Application programming interface) su ključna komponenta REST servisa.


API je skup smjernica i standarda za pristup web aplikaciji ili web alatu. API olakšava
programeru da izgradi aplikacije koje stupaju u interakciju sa drugim sistemima i servisima
tako što pružaju standardni način pristupa podacima i funkcionalnostima i manipulacije istih.

Postoji niz prednosti korištenja API-a za izgradnju aplikacija. Prva je da API-i mogu
olakšati programerima pristup i korištenje podataka i funkcionalnosti iz drugih sistema i
servisa. Ovo može uštedjeti vrijeme i trud eliminirajući potrebu za izradom prilagođenih
rješenja integracije. Drugo, API-i mogu pomoći u promoviranju interoperabilnosti između
različitih sistema i servisa, što im olakšava zajednički rad. Na poslijetku, API-i potpomažu
inovativnost tako što će programerima olakšati izgradnju novih aplikacija i servisa koje
koriste postojeće podatke i funkcionalnost.

REST i API-i su važne tehnologije za izgradnju skalabilnih i fleksibilnih web servisa.


REST upotreba HTTP-a i jednoobraznog interfejsa olakšavaju programerima izradu
aplikacija koje koriste web servise, dok API-i pružaju standardni način za pristup i
manipulaciju podacima i funkcionalnostima iz drugih sistema i usluga. Zajedno, ove
tehnologije igraju ključnu ulogu u omogućavanju razvoja modernih web aplikacija i servisa.

9
“What is an API?”, IBM, https://www.ibm.com/topics/api, (pristupljeno 21.02.2023)

10
6. IZRADA REST API-a

Po otvaranju projekta koji je preuzet sa stranice Spring Initializr započinje prvi korak
razvoja ovog projekta. Ovaj REST API će služiti za dohvatanje podataka o studentima iz
baze podataka. Za početak je u osnovnom paketu kreiran novi paket sa nazivom „student“.
U ovoj paketu će se nalaziti dvije Java klase koje će biti korištene za definisanje objekta
studenta i REST kontrolera.

6.1. Klasa Student

Klasa Student će biti korištena za opisivanje zapisa u bazi podataka. Kako bi fokus
ostao na sigurnosti i Spring Security-u, ova klasa će biti vrlo jednostavna te će sadržati samo
dva polja i to „studentId“ kao jedinstveni identifikator i „studentName“ kao polje sa nekim
korisnim podatkom.

Slika 3. Klasa Student (izvor: autor rada)

Kako se može i primjetiti na slici 3, klasa Student je anotirana sa @AllArgsConstructor i


@Getter anotacijama. Ove dvije klase pripadaju Lombok biblioteci o kojoj će biti govora u
jednom od narednih poglavlja. Ono što nam je za sada bitno je to da korištenjem ove dvije
anotacije možemo da koristimo automatski generisane gettere za sva polja ove klase, kao i
konstruktor za ovu klasu bez pisanja koda za iste.

6.2. REST Controller

REST kontroler „StudentController“ će biti klasa anotirana sa @RestController.


@RestController je anotacija u Spring Boot framework-u koja se koristi za označavanje
kontrolera koji će se koristiti za izradu REST API-ja. Kontroleri označeni ovom anotacijom
koriste Spring MVC arhitekturu i automatski mapiraju HTTP zahtjeve na odgovarajuće

11
metode. Kada se @RestController anotacija koristi na kontroleru, Spring Boot automatski
konfigurira Jackson Object Mapper koji konvertira objekte u JSON formatu. To znači da se
podaci automatski serijaliziraju u JSON formatu i šalju kao odgovor na HTTP zahtjev.

@RestController anotacija se koristi zajedno sa @RequestMapping anotacijom za


mapiranje HTTP metoda na odgovarajuće metode u kontroleru. Argument
@RequestMapping anotacije je putanja do API-a i u ovom primjeru će biti „api/students“.

Slika 4. Anotacije klase StudentController (izvor: autor rada)

Pored toga, @RestController anotacija se može koristiti sa @ExceptionHandler


anotacijom koja se koristi za mapiranje iznimki na odgovarajuće metode kontrolera koji će
se koristiti za obradu iznimki i generisanje odgovarajućeg odgovora, međutim, u ovom
primjeru se ova anotacija neće koristiti.

Unutar ovog REST kontrolera se definišu sve metode koje će biti izložene na ovom REST
API-u. Za izradu ovog projekta neće biti bitne sve operacije nad podacima u bazi podataka,
te će se stoga napraviti jedna metoda za dohvatanje podataka iz baze i to na način da će se
dohvatiti pojedinačan zapis prema jedinstvenom identifikatoru iz putanje – „studentId“.
Putanju do ove metode na API-u postavljamo pomoću anotacije @GetMapping koja kao
argument ima nastavak na prethodno postavljenu putanju do API-a.

Slika 5. Metoda za dohvatanje pojedinačnog zapisa iz baze podataka na osnovu jedinstvenog identifikatora
proslijeđenog u putanji (izvor: autor rada)

12
Prije nego pokrenemo aplikaciju potrebo je instancirati listu studenata kako bi
korištenjem ovog REST API-a zaista mogli vidjeti njegovu funkcionalnost. Ova lista će nam
trenutno zamijeniti zapise iz baze podataka u kojoj bi bili spremljeni studenti.

Slika 6. Instanca liste studenata sa 5 elemenata (izvor: autor rada)

Već samo sa ovim postavkama, REST API postaje dostupan na Tomcat serveru na
kojem se pokretanjem aplikacije kroz razvojno okruženje podiže instanca ove Spring Boot
aplikacije, a pristup istoj se vrši kroz pretraživač na adresi: „localhost:8080“ ili pomoću alata
za testiranje API-a poput Postman-a.

Postman je alat za razvoj API-a (Application Programming Interface) koji se koristi


za testiranje i razvoj web servisa. To je klijentski program koji se koristi za slanje HTTP
zahtjeva na web servise te za prikaz i analizu odgovora.

Slika 7. Poziv REST API-a za pristup zapisu iz baze podataka za element sa jedinstvenim identifikatorom 1
(izvor: autor rada)

13
Slika 8. HTTP GET zahtjev u Postman program (izvor: autor rada)

14
7. POMOĆNE BIBLIOTEKE

7.1. Spring WEB

Spring Web je modul Spring framework-a koji pruža veliki broj komponenta za
pravljenje web aplikacija u Javi. Izgrađen je na osnovu Spring jezgra i pruža niz mogućnosti
za izgradnju web aplikacija, uključujući podršku za izgradnju web kontrolera, resolvera
prikaza i validacije.

Jedna od ključnih karakteristika Spring Web-a je njegova podrška za web kontrolere,


koji su odgovorni za rukovanje dolaznim zahtjevima i generisanje odgovora. Spring Web
pruža niz različitih načina za izradu web kontrolera, uključujući korištenje anotacija i Java
konfiguraciju. Ovo programerima olakšava izradu web aplikacija koje mogu rukovati
širokim spektrom HTTP zahtjeva i generisati odgovore u različitim formatima, kao što su
HTML, XML ili JSON.

Spring Web takođe pruža podršku za resolvere prikaza, koji su odgovorni za


mapiranje imena elemenata prikaza u stvarne elemente. Ovo omogućava programerima da
koriste logičko ime elementa u svom kodu, dok se Spring Web brine o mapiranju tog imena
u stvarni predložak elementa. Spring Web podržava brojne tehnologije prikaza, uključujući
i JSP, Thymeleaf i FreeMarker kao neke od poznatijih.

Uz svoje osnovne karakteristike, Spring Web takođe pruža podršku za validaciju, koja
omogućava programerima da definišu ograničenja za podatke koje prihvata njihova web
aplikacija. Ovo može pomoći osiguravanju da aplikacija prima ispravne podatke i može
pomoći u sprječavanju grešaka i sigurnosnih propusta. Spring Web je kao dependency
uključen pri izradi ovog projekta u Spring Initializr-u te se već nalazi u pom.xml dokumentu.

Slika 9. Spring Web dependency iz pom.xml dokumenta (izvor: autor rada)

15
7.2. Spring DATA JPA

Spring Data JPA10 je modul Spring framework-a koji pruža podršku za izgradnju
Java aplikacija koje koriste Java Persistence API (JPA) 11 za pristup podacima pohranjenim
u bazi podataka. JPA je standard za pristup i manipulaciju podacima pohranjenim u bazi
podataka, a Spring Data JPA olakšava programerima da izgrade aplikacije koje koriste JPA
pružajući niz funkcija i komponenti.

Jedna od ključnih karakteristika Spring Data JPA je njegova podrška za interfejse


baza podataka. Interfejs spremišta je Java interfejs koji definiše skup metoda za izvođenje
uobičajenih CRUD (Create, Read, Update, Delete, osnovne o. Spring Data JPA pruža niz
interfejsa spremišta koje programeri mogu koristiti „out of the box“, ili mogu definirati
vlastite prilagođene interfejse prema bazama podataka kako bi odgovarali njihovim
specifičnim potrebama.

Spring Data JPA takođe pruža podršku za upite koristeći Java Persistence Query
Language (JPQL). JPQL je jezik sličan SQL-u koji omogućava programerima da definiraju
upite koristeći Java sintaksu. Spring Data JPA pruža mnoštvo različitih načina za definiranje
JPQL upita, uključujući korištenje naziva metoda i anotacije.

Pored svojih osnovnih karakteristika, Spring Data JPA takođe pruža podršku za
brojne dodatne funkcionalnosti, kao što su paginacija i auditing. Ove funkcije mogu olakšati
programerima da naprave robusnije i bogatije aplikacije koje trebaju pristupiti podacima
pohranjenim u bazi podataka i manipulirati njima.

10
“Spring Data JPA”, Spring, https://spring.io/projects/spring-data-jpa, (pristupljeno 20.12.2022)
11
“Introduction to the Java Persistence API”, Java EE 6 Tutorial,
https://docs.oracle.com/javaee/6/tutorial/doc/bnbpz.html, (pristupljeno 20.12.2022)

16
7.3. Lombok

Projekat Lombok 12je Java biblioteka koja pruža skup anotacija i alata za smanjenje
boilerplate koda u Java programima. Boilerplate kod je onaj koji se ponavlja i često nije
složen ali je neophodan za dati zadatak, kao što je postavljanje struktura podataka ili
upravljanje greškama. Lombok ima za cilj da smanji količinu boilerplate koda koji
programeri moraju da napišu pružanjem skupa anotacija koje automatski generišu ovaj kod.

Jedna od ključnih karakteristika Lomboka je njegova podrška za generisanje gettera,


settera i konstruktora za Java objekte. (@Getter, @Setter, @Data, @AllArgsConstructor,
@NoArgsConsctructor) Ove metode se obično koriste u Java programima za pristup i
manipulisanje svojstvima objekata, a Lombok ih može automatski generisati na osnovu polja
definisanih u klasi. Ovo programerima može uštedjeti vrijeme i trud eliminirajući potrebu
za ručnim pisanjem ovih metoda. Lombok pruža podršku za generisanje drugih uobičajenih
metoda, kao što su toString, equals i hashCode. Također pruža podršku za definiranje
nepromjenjivih objekata i generisanje builder design pattern-a, što dodatno olakšava izradu
i održavanje Java objekata.

Pored svojih osnovnih funkcionalnosti, Lombok takođe nudi brojne dodatne


anotacije koje dodatno smanjuju boilerplate kod. Na primjer, @Log anotacija se može
koristiti za generisanje logera za klasu, dok se @SneakyThrows bilješka može koristiti za
rukovanje provjerenim greškama na puno jednostavniji način, a naravno, tu je anotacija i za
Builder design pattern koji se koristi za stvaranje objekata sa kompleksnim konstruktorima
ili konstruktorima sa mnogo argumenata. Cilj ovog pattern-a je omogućiti stvaranje objekata
postupno, koristeći metode za postavljanje svakog parametra, umjesto da se svi parametri
moraju proslijediti kroz konstruktor. Korištenjem ovog pattern-a, kod za stvaranje objekta
postaje čitljiviji i lakše se razumije, a također omogućuje stvaranje objekata u više koraka,
što je korisno kada se rade kompleksni objekti. Lombok framework automatizira generisanje
Builder klase putem anotacije @Builder, što ubrzava proces izrade i smanjuje potrebu za
ručnim pisanjem koda.

12
Project Lombok, https://projectlombok.org/, (pristupljeno 22.012.2022)

17
8. SPRING SECURITY

Spring Security je okvir za osiguranje Spring i Spring boot aplikacija. Pruža niz
funkcija i komponenti za izgradnju sigurnih aplikacija, uključujući podršku za
autentifikaciju, autorizaciju i enkripciju.

Jedna od ključnih karakteristika Spring Security-a je njegova podrška za


autentifikaciju, što je proces provjere identiteta korisnika ili sistema. Spring Security pruža
brojne različite mehanizme provjere autentičnosti, uključujući podršku za autentifikaciju
zasnovanu na korisničkom imenu i lozinki, kao i podršku za naprednije mehanizme kao što
su dvofaktorska autentikacija i jedinstvena prijava.

Spring Security takođe pruža podršku za autorizaciju, što je proces odobravanja ili
odbijanja pristupa resursima na osnovu identiteta korisnika ili sistema. Spring Security pruža
niz različitih mehanizama za definiranje i primjenu pravila kontrole pristupa, uključujući
korištenje napomena, XML konfiguraciju i Java konfiguraciju.

Spring Security takođe pruža podršku i za šifriranje, upravljanje sesijama i


osiguranjem kanala komunikacija. Ove funkcije mogu pomoći da se jedna Java aplikacija
dodatno osigura, te da se zaštitite osjetljivi podaci korisnika.

Nezanemarujući sve ove funkcionalnosti i njihove benefine za aplikaciju, definitivno


najveća prednost Spring Security dependency-a je ta da njegova instalacija u projekat zaista
vrlo jednostavna.

Prvu funkcionalnost Spring Securrity-a već vidimo samim uključivanjem ovog


dependency-a u projekat.

Slika 10. Uključivanje Spring Security dependency-a u projekat


dodavanjem istog u pom.xml fajl (izvor: autor rada)

Već po dodavanju ovog dependency-a u pom.xml, pri prvom narednom pokretanju


aplikacije na prvi zahtjev za dohvatanje podataka iz baze, umjesto prikaza kakvog smo
vidjeli na slici 7. bit će otvoren prozor za unos kredencijala. Kako još uvijek nigdje u projektu
nije postavljena kombinacija kredencijala za pristu REST API-u, za korisničko ime će se

18
koristiti default-no korisničko ime „user“, a lozinku je moguće vidjeti u konzoli u kojoj je
pokrenuta sam projekat.

Bitno je znati da je generisana lozinka validna samo za trenutno pokrenutu instancu


aplikacije te će svakim narednim pokretanjem biti generisana nova lozinka.

Slika 11. Konzola u kojoj je pokrenut projekat


(izvor: autor rada)

Slika 12. Prozor za unos kredencijala(izvor: autor rada)

Slika 13. Test HTTP GET zahtjeva bez unijetih kredencijala (izvor: autor rada)

19
Testom slanja istog poziva iz Postman-a, na slici 13 vidimo da je vraćeni status za traženim
resursima 401: Unauthorized. Tek kada se unesu generisani kredencijali, pristup se odobrava
i podaci budu dohvaćeni kroz HTTP GET zahtjev, u pretraživaču imamo rezultat kakav smo
imali i prije postavljanja Sprig Security-a, a i u Postman-u vidimo resurs vraćen u JSON
formatu.

Slika 14. Dohvaćeni podaci nakon unosa BasicAuth parametara zahtjeva


(izvor: autor rada)

Kako se može vidjeti, već i bez podešavanja Spring Security pruža osnovnu
funkcionalnost autentifikacije za aplikaciju na kojoj je dodan. U nastavku prolazimo kroz
dodatne postavke autentifikacije pomoću Spring Security.

20
9. AUTENTIFIKACIJA

Autentifikacija je proces provjere identiteta korisnika. To se obično radi putem


korisničkog imena i lozinke, koje korisnik unosi kako bi se autentificirao. Ako se korisničko
ime i lozinka podudaraju sa onima koji su pohranjeni u sistemu aplikaicje, korisnik se smatra
autentificiranim i dobiva pristup zaštićenim dijelovima aplikacije.

Postoji nekoliko načina autentifikacije:

• Korisničko ime i lozinka: ovo je najčešći način autentifikacije, korisnik unosi svoje
korisničko ime i lozinku, te ih aplikacija provjerava sa onima koji su pohranjeni u
bazi podataka
• Token-based: ovaj način autentifikacije koristi se kada se korisnik autentificira
jednom, a aplikacija mu daje token koji se koristi za svaki naredni zahtjev. Token
se provjerava na svakom zahtjevu kako bi se utvrdilo da li korisnik ima pravo
pristupa zaštićenim dijelovima aplikacije.
• Biometrija: ovaj način autentifikacije koristi se kada se koriste senzori za
skeniranje biometričkih podataka korisnika, poput otisaka prstiju, prepoznavanja
lica ili glasa.
• Certifikati: ovaj način autentifikacije se koristi kada se koriste digitalni certifikati
za potvrdu identiteta korisnika.
Kao prvi korak u dodavanju autentifikacije koju ćemo konfiurisati u ovaj projekat
dodajemo tzv. „Basic Auth“ autentifikaciju. Na slici 15 možemo vidjeti dijagram
cijelog procesa, a u nastavku slijedi objašnjenje.

Slika 15. Dijagram toka Basic Auth procesa (izvor: autor rada)

21
Basic Auth je jedan od najčešćih mehanizama autentifikacije koji se koristi za
osiguravanje pristupa web servisima. Ovaj mehanizam koristi kombinaciju korisničkog
imena i lozinke za način provjere identiteta korisnika.

Proces autentifikacije sa Basic Auth se obično sastoji od sljedećih koraka:

1. Korisnik šalje HTTP zahtjev na web servis.


2. Web servis odgovara sa HTTP status kodom 401 (Unauthorized) i zahtijeva da se
proslijedi korisničko ime i lozinka.
3. Korisnik šalje ponovni zahtjev sa korisničkim imenom i lozinkom u formatu
"username:password" kodiranim u Base64.
4. Web servis provjerava korisničko ime i lozinku sa onima koji su pohranjeni u bazi
podataka ili nekom drugom mjestu za pohranu podataka.
5. Ako se korisničko ime i lozinka podudaraju, web servis odgovara sa HTTP status
kodom 200 (OK) i dopušta pristup zaštićenim dijelovima aplikacije.
6. Ako se korisničko ime i lozinka ne podudaraju, web servis odgovara sa HTTP status
kodom 401 (Unauthorized) i odbija pristup.

Sada kad je jasan slijed koraka i procedura koje se moraju izvršiti da bi se postigao bazični
nivo autentifikacije, može se krenuti na implementaciju iste unutar ovog projekta. Potrebno
je napraviti novi paket u kojem će se nalaziti klase za konfiguraciju autentifikacije. U ovom
slučaju taj paket će biti nazvan „security“. Prva klasa koja će biti dodana je klasa
ApplicationSecurityConfig. Ova klasa će zapravo predstavljati Web Security Confiurer
Adapter, praktično konfiguraciju Web Security-a korz Spring Security.

Slika 16. Klasa ApplicationSecurityConfig i metoda configure (izvor: autor rada)

22
Ova klasa će imati dvije anotacije. @Configuration anotacija se koristi u Spring-u za
označavanje klasa koja sadrži metode za konfigurisanje elemenata aplikacije. Ova anotacija
označava da se klasa koristi za definisanje bean-ova (Spring Java objekata instanciranih u
runtime-u aplikacije), pa će i ovdje označavati da se radi o konfiguracijskoj klasi.
@EnableWebSecurity anotacija omogućava uključivanje sigurnosti web aplikacije. Ovu
anotaciju u kombinaciji sa @Configuration anotacijom koristimo za aktiviranje
podrazumijevanog sigurnosnog konfiguracijskog okvira za web aplikacije koji se temelji na
Spring Security biblioteci. Spring Framework će na osnovu anotacija u ovoj klasi automatski
konfigurisati sigurnosne postavke za aplikaciju, kao što su autentifikacija i autorizacija
korisnika, zaštita od napada (CSRF, XSS) itd. Kako bi postigli osnovu BasicAuth
autentifikacije, dovoljno je da unutar konfiguracijske klase napravimo “override” metode
configure. Za proslijeđeni http zahtjev, ova metoda osigurava da se za svaki autorizirani
zahtjev traži autentifikacija od korisnika koisteći BasicAuth metodu autentifikacije.

Nakon ove izmjene, za pristup bilo kojem end point-u API-a neophodna će biti
autentifikacija pomoću korisničkog imena “user” i generisane lozinke.

Međutim, to nije očekivano ponašanje jedne web aplikacije. Ono što korisnik očekuje
je da u aplikaciju može ući upisivanjem svojih proizvoljno definisanih kredencijala, koji bi
bili spremljeni u neku bazu, a aplikacija bi pri njegovoj akciji login-a trebala provjeriti da li
uneseni par kredencijala odgovara onome iz baze.

Naredni korak će biti dodati provizioniranje korisnika. Kako bi kreirali bazu


korisnika, potrebno je da znamo nekoliko stvari vezanih za provizioniranje korisnika. Prije
svega, svaki korisnik bi trebao imati korisničko ime koje mora biti jedinstveno. Zatim, treba
da ima lozinku. Lozinka se u bazi ne bi trebala čuvati kao običan tekst već ju je neophodno
enkriptovati. Korisnik bi takođe trebao da ima i ulogu na osnovu koje će dobiti ovlasti. Ovaj
dio je opcionalan, ali je dobra ideja imati ograničenja pristupa za pojedine tipove korisnika
kako bi se prikupljeni podaci zaštitili od neovlaštenog pristupa i izmjene, a samim time se i
osigurao veći integritet podataka.

Za prvo provizioniranje korisnika napravit ćemo korisnika u radnoj memoriji


aplikacije. Za pravljenje korisnika kreiran je override metode userDetailsService. Ako
otvorimo implementaciju klase UserDetailsService, ustvari vidimo da je ovo interface (slika
17) koji zapravo koristi implementira šest različitih servisa/menadžera za provizioniranje i
druge operacije nad korisnicima. Onaj koji je nama u ovom trenutku posebno zanimljiv jeste

23
InMemoryUserDetailsManager. Ovaj menadžer nam dopušta da na jednostavan način,
korištenjem builder pattern-a, kreiramo i dalje upravljamo korisnicima čiji će podaci biti
spremljeni u radnu memoriju aplikacije.

Slika 17. Interface UserDetailsService (izvor: autor rada)

Provizioniranje korisnika u radnoj memoriji se radi pomoću builder() metode koju


pruža UserDetails klasa, a koja će biti korištena za ovaj slučaj.

Slika 18. Metoda userDetailsService i provizionirani korisnik “admin” (izvor: autor rada)

Kao što je već i rečeno, lozinka radi zaštite mora biti enkodirana, pa će nas Spring
pri loginu ovog korisnika upozoriti na to da lozinka nije zaštićena, te se korisnik sa
nezaštićenim kredencijalima neće moći logovati i pristupiti aplikaciji.

Slika 19. Upozorenje za lozinku koja nije enkodirana (izvor: autor rada)

Za enkoridarnje lozinke se najčešće koristi već postojeći interface za enkodiranje


lozinki unutar Spring Security-a uz jedan od najpopularnijih enkodera za kredencijale

24
BCript13. Kako ćemo koristiti već gotov enkoder, potrebno je napraviti klasu. Ova klasa će
da služi kao konfiguracija za enkoder, te će instanciranjem vraćati PasswordEncoder kao
bean.

Slika 20. Klasa PaswordConfig (izvor: autor rada)

Kada smo napravili ovu klasu, možemo se vratiti u ApplicationSecurityConfig klasu


i napraviti „Autowireing“ ovog, sada već dependency-a. @Autowired anotacija je dio Spring
Framework-a i koristi se za automatsko ubacivanje dependency-a u komponente aplikacije.
Ova anotacija se koristi za automatsko povezivanje bean-ova koji su definirani u Spring
kontekstu sa varijablama ili konstruktorima klase u kojoj se koristi anotacija. Anotacija se
može koristiti na varijabli, konstruktoru ili setter metodi. Spring će automatski povezati bean
koji odgovara tipu varijable ili argumentu konstruktora. Na slici 21 je prikazan kod koji radi
upravo autowireing PasswordEncodera. Sa ovim dependency-em možemo izvršiti
enkodiranje korisničke lozinke pa će poziv builder() metode sada izgledati kao na slici 22, a
upozorenja za neenkodiranu lozinku više neće biti.

13
“Class BCryptPasswordEncoder”, Spring Docs, https://docs.spring.io/spring-
security/site/docs/current/api/org/springframework/security/crypto/bcrypt/BCryptPasswordEncoder.html,
pristupljeno (06.01.2023)

25
Slika 21. Kod za Autowire-ing dependency-a (izvor: autor rada)

Slika 22. Builder metoda sa pozivom enkodera (izvor: autor rada)

26
10. ULOGE I DOZVOLE

Uloge i dozvole se koriste u gotovo svim aplikacijama kako bi se kontrolisao pristup


određenim funkcionalnostima i mogućnostima koje aplikaci nudi svojim korisnicima. Uloge
se koriste da se grupišu setovi dozvola koje su dodjeljene pojedinačnim korisnicima, pa tako
na primjer, aplikacija najčešće ima ulogu pod nazivom "admin" koja korisniku daje pristup
svim funkcionalnostima aplikacije, dok uloga pod nazivom "user" daje pristup samo
podskupu funkcionalnosti.

Dozvole, sa druge strane, su specifične radnje ili operacije koje su korisniku


dopuštene za izvršavanje. Na primjer, korisnik sa dozvolom čitanja može vidjeti određene
stranice ili resurse, ali ne može napraviti izmjene nad njima, dok korisnik sa dozvolom
pisanja ima mogućnost i da napravi izmjene na određenim stranicama ili resursima.

Uloge i dozvole se obično čuvaju u bazi podataka aplikacije i koriste se za


provođenje pravila kontrole pristupa. Kada korisnik pokuša pristupiti određenoj
funkcionalnosti ili resursu, aplikacija provjerava ulogu i dozvole za tog korisnika da utvrdi
da li je dopušteno da izvrši zahtijevanu radnju.

Važno je napomenuti da se uloge i dopuštenja mogu implementirati na različite


načine u zavisnosti od aplikacije i zahtjeva za sigurnošću.

Slika 23. Enum klasa za dozvole (izvor: autor rada)

27
Za potrebe ove aplikacije, uloge i dozvole ćemo navesti u po jednoj java enum klasi.
Uz enum klase kreirat ćemo i konstruktor i getter koristeći Lombok.

Slika 24. Enum klasa za uloge (izvor: autor rada)

Pri prvom testu ćemo Admin korisnicima dati sve dozvole, dok studenti neće imati
dozvolu za bilo šta. Nakon što su u ovim enum klasama definisane uloge i dozvole, možemo
kreirati korisnike sa predefinisanim ulogama.

Slika 25. Korisnici sa predefinisanim ulogama (izvor: autor rada)

U ovom trenutku oba korisnika i dalje mogu pristupati svim resursima koje ovaj API
nudi. Kako bi ograničili pristup, koristit ćemo AntMatcher-e. Unutar configure() metode

28
ćemo ubaciti AntMatchere koji će dozvoliti korištenje API-a samo Admin korisnicima i to
na način prikazan na slici 26. U suprotnom, korisnik će dobiti status kod 403 sa porukom
„Forbidden“ što će značiti da taj korisnik nema dozvole za korištenje tog resursa.

Slika 26. Ant Matcher za ograničavanje pristupa API-u samo za ADMIN korisnike (izvor: autor rada)

Sada možemo kreirati i početnu stranicu index.html našeg API-a. Na njoj će biti
naslov API-a i dugme koje će voditi na poziv “/api/students/all”. Uz nju će biti kreiran i
odgovarajući styles.css.

Slika 27. Početna stranica API-a (izvor: autor rada)

Kada imamo početnu stranicu, želimo dopustiti svima da je vide, ali samo onima koji
su autentifikovani i imaju dozvolu da koriste resurse. To ćemo uraditi dodavanjem još jednog
Ant Matcher-a (slika 28). U Ant Matcher ćemo dodati “index.html“ i „/css/*“ te ćemo
odabrati opciju permitAll() što će značiti da su index.html i svi resursi iz foldera css dostupni
svima koji pristupaju našem API-u.

29
Slika 28. Ant Matcher za dozvolu pristupa početnoj stranici svim korisnicima (izvor: autor rada)

Dokazali smo da Spring Security može da bez problema ograniči pristup našem API-u de ta
upravlja dozvolama i korisnicima. Sada ćemo pristup resursima na putanji /api/** dozvoliti
samo studentima na način da ćemo umjesto hasRole(ADMIN.name()) u Ant Matcher ubaciti
hasRole(STUDENT.name()).

Slika 29. Prikaz funkcionalnosti u administracijskom API kontroleru (izvor: autor rada)

30
Time uklanjamo dozvole za admin korisnike za ovaj dio API-a. To je upravo ono što
želimo iz razloga što ćemo za administraciju napraviti novi API koji će davati nešto više
funkcionalnosti pored samog čitanja podataka.

Za administratore je kreiran poseban kontroler sa funkcionalnostima pregleda svih


studenata, kreiranja novog studenta, izmjene postojećih podataka za studenta i brisanja. Ove
metode će biti izložene na REST API-u na adresi „localhost:8080/management/api“. Kako
još nismo podesili pristup resursima putem ovog API-a, pozivi ovih metoda neće moći biti
mogući te ćemo dobijati status kod 403 sa porukom „Forbidden“. Na slici 29. vidimo novu
anotaciju @PreAuthorize. Ova anotacija pojednostavljuje ograničenje pristupa endpoint-ima
jednog REST API-a, te se koristi na način da ako je uslov koji se proslijeđuje kao parametar
ispunjen, pristup metodi će biti omogućen. Na početnoj stranici će se sada nalaziti i novo
dugme za pristup menadžment API-u.

Slika 30. Početna stranica sa novim dugmetom za pristum menadžmet API-u (izvor: autor rada)

31
11. CSRF

Cross-Site Request Forgery (CSRF) je vrsta ranjivosti web aplikacije koja napadaču
omogućuje izvršavanje neželjenih radnji na web stranici ili web aplikaciji u ime
autentificiranog korisnika. „To je napad koji navede korisnički uređaj da izvršava neželjene
akcije na web aplikaciji na kojoj je korisnik trenutno autentificiran.“14 Napad funkcionira
tako da prevari korisnikov pretraživač da pošalje zahtjev ciljanoj web stranici ili aplikaciji,
koristeći korisničke kredencijale i druge autentifikatore, bez znanja ili pristanka korisnika.

Ovaj napad se najčešće izvodi slijedećim koracima:

• Napadač krivotvori zahtjev unutar zlonamjerne web stranice ili forme .


• Korisnik posjeti zlonamjernu web stranicu ili klikne na link, što uzrokuje da
korisnikov pretraživač pošalje zahtjev ciljanoj web stranici ili aplikaciji.
• Ciljana web stranica ili aplikacija prima zahtjev, a budući da se čini da dolazi od
autentificiranog korisnika, obrađuje zahtjev i izvodi odgovarajuću radnju.

CSRF napadi mogu se spriječiti korištenjem mjera kao što je dodavanje CSRF tokena
svakom obrascu, osiguravanje da se zahtjevi prihvaćaju samo od autentificiranih korisnika i
implementacija drugih sigurnosnih mjera za sprječavanje neovlaštenog pristupa.

Spring pruža već out-of-the-box CSRF zaštitu. Prema zadanim postavkama, Spring
generiše jedinstveni token za svaku sesiju i uključuje ga u HTML obrazac kao skriveno polje.
Kada korisnik podnese obrazac, token je uključen u zahtjev, a Spring ga uspoređuje s
tokenom povezanim s korisnikovom sesijom kako bi osigurao da je zahtjev legitiman.

Sada ćemo vidjeti šta to u praksi znači. Kada se korisnik uspješno logira po prvi put,
kreira se njegov XSRF Token sa kojim će moći da poziva PUT, POST i DELETE metode
REST API-a. Token će biti potreban za navedene operacije, te neophodno ga je spremiti
kako bi se u budućnosti mogao koristiti u header-u zahtjeva. Za čuvanje tokena i jednostavno
korištenje iskoristit ćemo klasu CsrfTokenRepository iz Spring Security biblioteke. Tu su

14
KristenS., “Cross Site Request Forgery (CSRF)”, OWASP, https://owasp.org/www-community/attacks/csrf,
pristupljeno (21.2.2023.)

32
definisane metode kojima će se generisani token spremati za daljnje korištenje i kada bude
potrebe dodati u header-e zahtjeva koji se šalju.

Za dodavanje ove klase potrebno je samo dodati jednu liniju koda unutar
AppllicationSecurityConfig klase u metodi configure. Na slici 31. je prikazana metoda
nakon dodavanja CsrfTokenRepository-a.

Slika 31. Metoda configure sa dodanim postavkama za CSRF zaštitu (izvor: autor rada)

Sa time bi završili sva potrebna podešavanja za zaštitu od CSRF napada. Međutim, kako ovo
nije aplikacija koju ćemo hostati na internet, prema Spring Security dokumentaciji za CSRF,
uključivanje zaštite od CSRF napada nije potrebno te ćemo ovu liniju jednostavno zamijeniti
sa „.csrf().disable()“ te na taj način isključiti nepotrebnu zaštitu za našu aplikaciju dok je ista
u offline režimu rada.

33
12. SESIJE I KOLAČIĆI

Do sada smo u projektu koristili BasicAuth metodu autentifikacije. BasicAuth pri


Log In-u od korisnika traži kredencijale u pop-up prozoru pretraživača koji nije moguće
modifikovati. Uz to, BasicAuth ne nudi opciju Log Out-a. Kako bi mogli korisniku
omogućiti i tu funkcionalnost koristit ćemo alternativnu metodu autentifikacije sa
korisničkim imenom i lozinkom, Form LogIn. Form LogIn će nam pored toga, omogućiti i
upravljanje sesijama. Form Login ima nešto drugačiji tok operacija što možemo vidjeti na
slici 32.

Slika 32. Dijagram toka Form Login metode autentifikacije (izvor: autor rada)

Spring Security nam i za form Login već nudi gotov paket koji možeko koristiti.
Kada je metoda configure podešena kao na slici 33., pri pokretanju aplikacije vidimo
slijedeći ekran (slika 34.).

34
Slika 33. configure metoda sa podešenom formLogin autentifikacijom (izvor: autor rada)

Slika 34. Login forma (izvor: autor rada)


Nakon logina u „Developer tools“ pod sekcijom Application/storage/cookies
možemo vidjeti da sada postoji jedan kolačić pod imenom „JSESSIONID“, a u njemu se
nalazi spremljen identifikator sesije.

Slika 35. Kolačić sa identifikatorom sesije (izvor: autor rada)

35
12.1. O kolačićima

Kolačići (engl. "cookies") su male tekstualne datoteke koje se pohranjuju na računaru


ili mobilnom uređaju kada korisnik posjeti web stranicu. Oni su dizajnirani kako bi se
korisnicima pružilo bolje iskustvo korištenja web stranica, kao što su prijava, spremanje
postavki stranice i personalizacija sadržaja. Kolačići se koriste za pohranu različitih
informacija, kao što su postavke jezika, korisničko ime i lozinka, sadržaj košarice na web
prodajnim mjestima ili neke druge specifične postavke jedne stranice.

Već smo spomenuli da formLogin dopušta modifikovanje stranice sa login


formom, pa ćemo iskoristiti i tu mogućnost koju nam formLogin nudi. Prije nego krenemo
na dodavanje novih HTML stranica, uvest ćemo biblioteku Thymeleaf. Thymeleaf je Java
server-side generator koji omogućava stvaranje dinamičkih predložaka za web stranice.
Nakon dodavanja ove biblioteke, potrebno je u configure metodinaznačiti da se koristi
posebno definisana login stranica.

Slika 36. Konfiguracija za korisnički definisanu login stranicu (izvor: autor rada)

Trenutno, zahtjev mapiran na endpointu /login ne radi ništa jer za njega još uvijek nemamo
kontroler. Naredni korak će nam biti onda napraviti kontroler koji će biti dostupan svima i
koji će otvarati login stranicu. Budući da ćemo koristiti Thymeleaf, u novom paketu
„controller“ pravimo novi kontroler pod nazivom TemplateController. Unutar tog kontrolera
ćemo odmah napraviti dva endpoint-a, jedan za login, a drugi za stranicu kurseva koja će
biti otvorena po uspješnom loginu.

36
Slika 37. Klasa TemplateController (izvor: autor rada)

Kako bi nakon uspješnog login-a bili preusmjereni na stranicu „courses“, u configure metodi
ćemo dodati još jednu opciju a to je defaultSuccessUrl.

Slika 38. defaultSuccessUrl opcija u configure metodi (izvor: autor rada)

Sada možemo kreirati naše korisnički definisane login i courses stranice. Za potrebe ovog
primjera, to će biti dvije vrlo jednostavne stranice, a njihov izgled se može vidjeti na slikama
39 i 40.

Slika 39. Izgled login stranice (izvor: autor rada)

37
Slika 40. Izgled courses stranice (izvor: autor rada)

12.2. O sesijama

Nakon što se korisnik loguje, dobije svoj SESSIONID koji vrijedi 30 minuta prema
unaprijed definisanoj vrijednosti. To znači da će se korisnik nakon 30 minuta neaktivnosti
morati ponovo ulogovati u aplikaciju. Naravno, u nekim slučajevima to nije nešto što želimo,
te bi rješenje ovoga bilo da se korisniku ponudi opcija „Zapamti me“ što će njegovu sesiju
po predefinisanoj vrijedosti produžiti sa 30 minuta na dvije sedmice. Ovo će praktično reći
Spring Security-u da napravi novi kolačić koji će sadržati hash trenutnog SESSIONID-a i
maksimalno vrijeme trajaja tog SESSIONID-a.

Sve ove vrijednosti se pohranjuju u radnu memoriju aplikacije, pa ako se desi da iz


bilo kojeg razloga aplikacija bude zaustavljena, sve sesije i kolačići se brišu te više nemamo
zapise o tome koliko traje korisnikova sesija i do kada je validna. Pametna opcija bi bila
pohranjivati zapise u bazu podataka, ali za sada nećemo implementirati taj dio.

Remember me opcija se takođe može dodatno definisati na način da se postavi dužina


trajanja sesije ako korisnik želi da ga aplikacija zapamti. Na slici 40 vidimo kako izgleda
posdešavanje rememberMe opcije.

38
Slika 41. Postavljanje rememberMe opcije unutar configure metode (izvor: autor rada)

Još jednu funkcionalnost ćemo ubaciti na ovaj dio aplikacije, a to je logout. Na


logout-u želimo da se svi podaci koji nam više ne trebaju uklone. To ćemo uraditi na način
prikazan na slici 42. Pri logout-u želimo da se podaci o autentifikaciji uklone, da se invalidira
sesija te da se obrišu kolačići, a nakon toga da se vratimo na login stranicu.

Slika 42. Postavljanje logout opcije u configure metodi (izvor: autor rada)

Sada imamo stranicu koja radi osnovni login/logout i upravlja dužinom trajanja korisničkih
sesija.

39
13. POVEZIVANJE SA BAZAMA PODATAKA

Već smo na nekoliko mjesta spominjali baze podataka i njihov značaj. Do sada smo
napravili dva korisnika pomoću userDetailsService-a i InMemoryUserDetailsManager-a.
Sada ćemo u projekat dodati interface koji ćemo moći koristiti ako bi nekada željeli ove
korisnike spremiti u bazu podataka.

Prije svega, moramo napraviti klasu korisnika. U novom paketu “auth” pravimo
klasu ApplicationUser koja će implementirati već korišteni interface Spring Security-a za
korisnike UserDetails.

Slika 43. Klasa ApplicationUser (izvor: autor rada)

Pored modela koji smo upravo napravili, bit će nam potreban i servis koji ćemo
koristiti za komunikaciju sa bazom podataka. U istom paketu pravimo još jednu klasu koja
će se u ovom slučaju zvati ApplicationUserService i koja će implementirati
UserDetailsService. Prije nego što uradimo Override metode iz interface-a
UserDetailsService, napravit ćemo i samo svoj interface. Ovaj interface će imati naziv
ApplicationUserDao i u sebi će imati jednu metodu koja će vraćati Optional
ApplicationUser-a prema korisničkom imenu koje se proslijedi.

40
Slika 44. Interface ApplicationUserDao (izvor: autor rada)

Sada kad imamo interface, možemo do kraja implementirati klasu ApplicationUserService.


Ova klasa će imati jednu metodu za dohvatanje korisnika po korisničkom imenu. Takođe, u
ovoj klasi će biti uključen i interface koji smo upravo napravili na način da će se odraditi
dependency injection pomoću anotacije @Autowired. Uz to, dodajemo još jednu klasu,
RepoApplicationUserDaoService, koja će za naš primjer biti mock-up konekcije na
repozitorij.

Slika 45. Klasa ApplicationUserService (izvor: autor rada)

Slika 46. Klasa RepoApplicationUserDaoSerivce (izvor: autor rada)

41
Sa svim ovim klasama napravljenim, sada možemo izmijeniti klasu
ApplicationSecurityConfig tako da se unutar nje više ne spremaju korisnici. Kako bi
omogućili komunikaciju sa repozitorijem, potrebno je da napravimo
DaoAuthenticationProvider. Ovaj metod će ustvari instancirati Bean providera kojeg ćemo
dalje korsititi kao interface prema bazi.

Slika 47. DaoAuthnenticationProvider Bean (izvor: autor rada)

Nakon ovih koraka, aplikacija bi trebala da radi kao i do sada, samo što će korisničkim
podacima pristupati koristeći RepoApplicationUserDaoService. Implementacijom ovakvog
jednog interface-a u novoj klasi za povezivanje sa bilo kojom bazom podataka smo praktično
omogućili da naša aplikacija konzumira podatke iz bilo koje druge odabrane baze podataka
bez obzira na tip čime se postiže veliki stepen modularnosti i kompatibilnosti.

Na samom kraju kada se instancira i baza podataka koja se može uvezati pomoću
jednostavnog interface-a, imamo aplikaciju koja nudi dva odvojena REST API-a, upravlja
ulogama korisnika i dozvolama koje su vezane za njihove uloge, vodi brigu o korisničkim
sesijama, implementira „form based“ metodu autentifikacije korisnika, a sve pomoću Spring
Boot framework-a i Spring Security biblioteke.

42
ZAKLJUČAK

Korištenje Spring Boot frameworka i biblioteka koje uključuje omogućilo je razvoj


robusne i skalabilne aplikacije koja pruža odvojene funkcionalnosti za dva tipa korisnika,
autentifikaciju i autorizaciju korisnika i upravljanjem sesijama.

Implementacija kontrole pristupa temeljene na ulogama i upravljanje dopuštenjima


pruža učinkovit način upravljanja korisničkim pristupom različitim resursima i
funkcionalnostima aplikacije što zasigurno može pomoći osiguranju da korisnici mogu
pristupiti samo opcijama i podacima za koje su ovlašteni, čime se smanjuje rizik od povrede
integriteta podataka i drugih sličnih sigurnosnih propusta.

Upotreba frameworka Spring Boot i svih navedenih biblioteka sa posebnim


akcentom na Spring Security je znatno pomogla u smanjenju vremena i truda uloženog u
razvoj. Kao rezultat toga, programeri se mogu više usredotočiti na specifičnu poslovnu
logiku aplikacije, umjesto da brinu o detaljima implementacije nižih nivoa.

Dodatno, povezivanje na bazu podataka koja se može lako uvesti putem


jednostavnog interface-a pruža učinkovit i jednostavan način pohrane svih bitnih podataka
ove aplikacije.

Cilj nam je bio naglasiti važnost odabira odgovarajućih razvojnih alata i tehnologija
koji mogu pojednostaviti razvojni proces i pružiti potrebnu funkcionalnost sa jako malo
truda i osnovnim znanjem. Nadalje, implementacija sigurnosnih mjera, kao što su
autentifikacija i autorizacija, ključne su za osiguranje sigurnosti korisničkih podataka i
sprječavanje neovlaštenog pristupa.

Na samom kraju možemo zaključiti da uz moćne alate i tehnologije koji su danas


dostupni, korištenjem predviđenih procedura i najboljih praksi u izgradnji softvera, izrada
izuzetno funkcionalnih, ali i sigurnih web aplikacija je sve jednostavnija i pruža priliku
velikom broju inžinjera da se odvaže i krenu u izradu vlastitog softvera za najrazličitije
namjene.

43
LITERATURA

Elektronski izvori:

1. Oracle Help center, “Java SE, JDK 17 Documentation”,


https://docs.oracle.com/en/java/javase/17/, (pristupljeno 18.12.2022.)
2. Apache Maven Project, “Welcome to Maven”, https://maven.apache.org/, (pristupljeno
19.12.2022)

3. https://spring.io/, pristupljeno 20.12.2022.


4. https://spring.io/projects/spring-security, pristupljeno 21.12.2022
5. Oravle Java documentation, “Dependency Injection”,
https://docs.oracle.com/javaee/dependency-injection, (pristupljeno 20.12.2022)
6. Spring Initializr tool, https://start.spring.io/, (pristupljeno 20.12.2022)
7. IntelliJ IDEA, Java and Kotlin IDE, https://www.jetbrains.com/idea/, (pristupljeno
12.12.2022)
8. Restful API, “What is REST”, https://restfulapi.net/, (pristupljeno 21.2.2023)
9. Cloudflare, “What is HTTP”,
https://www.cloudflare.com/learning/ddos/glossary/hypertext-transfer-protocol-http/,
(pristupljeno 21.2.2023)
10. IBM, “What is an API?”, https://www.ibm.com/topics/api, (pristupljeno 21.02.2023)

11. Spring, “Spring Data JPA”, https://spring.io/projects/spring-data-jpa, (pristupljeno


20.12.2022)
12. Java EE 6 Tutorial, “Introduction to the Java Persistence API”,
https://docs.oracle.com/javaee/6/tutorial/doc/bnbpz.html, (pristupljeno 20.12.2022)
13. Project Lombok, https://projectlombok.org/, (pristupljeno 22.012.2022)
14. Spring Docs, “Class BCryptPasswordEncoder”, https://docs.spring.io/spring-
security/site/docs/current/api/org/springframework/security/crypto/bcrypt/BCryptPassword
Encoder.html, pristupljeno (06.01.2023)
15. KristenS, at OWASP, “Cross Site Request Forgery (CSRF)”, https://owasp.org/www-
community/attacks/csrf, pristupljeno (21.2.2023.)

Knjige:

1. Head First Design Patterns: A Brain-Friendly Guide 1st Edition, Eric Freeman & Elisabeth
Robson, 2004

44
2. Niko Schwarz, Mircea Lungu, Oscar Nierstrasz, “Seuss: Decoupling responsibilities from
static methods for fine-grained configurability”, Journal of Object Technology, Volume 11,
no. 1 (April 2012)
3. Spring Boot in Action, Craig Walls, 2015
4. Spring Boot: Up & Running, Mark Heckler, O’Reilly 2021

45
POPIS SKRAĆENICA

REST Represetnational State Transfer

API Application Programming Interface

SQL Structured Query Language

XEE XML External Entity

DDOS Distributed Denial of Service.

JVM Java Virtual Machine

POM Project Object Model

XML eXtensible Markup Language

AOP Aspect-Oriented Programming

MVC Model-View-Controller

JPA Java Persistence API

WAR Web Application Archive

IDE Integrated Development Environment

HTTP Hypertext Transfer Protocol

JSON JavaScript Object Notation

HTML Hypertext Markup Language

CRUD Create, Read, Update, Delete

JPQL Java Persistence Query Language

CSRF Cross-Site Request Forgery

46
PRILOZI

1. Repozitorij projekta iz diplomskog rada:


https://github.com/beslagicadin/Diplomski_rad_projekat

47

You might also like