Zabezpieczenie aplikacji przed nieuprawnionym dost臋pem to jedna z najwa偶niejszych rzeczy do zrobienia przed wypuszczeniem programu do klient贸w. Nie mo偶emy sobie pozwoli膰 na to, by dowolny u偶ytkownik aplikacji mia艂 dost臋p do wszystkich danych i funkcji systemu. Na szcz臋艣cie w Springu mo偶emy 艂atwo o to zadba膰 z pomoc膮 projektu Spring Security, a w tym wpisie poka偶臋 Ci jak to zrobi膰 馃檪
Aby doda膰 Spring Security do projektu w Spring Boocie b臋dziemy potrzebowa膰 trzech sk艂adnik贸w:
- odpowiednie zale偶no艣ci w projekcie,
- konfiguracja endpoint贸w,
- konfiguracja u偶ytkownik贸w.
馃摴 Wolisz obejrze膰 wideo? Na ko艅cu wpisu znajdziesz link do webinaru z tym tematem.
Dodanie zale偶no艣ci
Tutaj sprawa jest prosta. Wystarczy doda膰 odpowiedni starter do zale偶no艣ci (tu przyk艂ad w Mavenie i pliku pom.xml
) i voila – Security mamy dodane do projektu.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
Konfiguracja endpoint贸w
W tym momencie ca艂a Twoja aplikacja jest zabezpieczona przed nieuprawnionym dost臋pem, a jedyny spos贸b by si臋 do niej dosta膰 to skorzystanie z uwierzytelnienia Basic Auth i dw贸ch parametr贸w:
- nazwa u偶ytkownika – domy艣lnie
user
- has艂o – wygenerowane na Twojej konsoli w formacie UUID, np.
63474724-1ceb-4a7d-bc0e-119fd728a915
- szukaj wpisu
Using generated security password: 63474724-1ceb-4a7d-bc0e-119fd728a915
- szukaj wpisu
Co je艣li nie chcesz, aby wszystko by艂o zabezpieczone?
W tym celu musisz nadpisa膰 klas臋 WebSecurityConfigurerAdapter
, doda膰 j膮 do kontekstu Springa (np. adnotacj膮 @Configuration
) i zdefiniowa膰 w艂asne regu艂y autoryzacji.
@Configuration
class BookaroSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.mvcMatchers(HttpMethod.GET, "/catalog/**").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
}
}
Powy偶szy fragment oznacza:
- requesty GET pod adres
/catalog
i jego pod艣cie偶ki maj膮 by膰 dost臋pne dla wszystkich u偶ytkownik贸w –mvcMatchers(HttpMethod.GET, "/catalog/**").permitAll()
- pozosta艂e 偶膮dania –
anyRequest().authenticated()
wymagaj膮 bycia uwierzytelnionym - dodatkowo pozwalamy na dost臋p za pomoc膮 Basic Auth –
.and().httpBasic()
Gotowe. Teraz mo偶esz sprawdzi膰, 偶e nie wszystkie endpointy wymagaj膮 autoryzacji w Twojej aplikacji.
Konfiguracja u偶ytkownik贸w
U偶ytkownik贸w mo偶na konfigurowa膰 na trzy sposoby:
- w pami臋ci aplikacji,
- w bazie danych aplikacji,
- z zewn臋trznych dostawc贸w.
W tym artykule skupimy si臋 na pierwszym sposobie.
Aby skonfigurowa膰 u偶ytkownik贸w w pami臋ci wracamy do klasy konfiguracyjnej BookaroSecurityConfiguration
i nadpisujemy kolejn膮 metod臋.
@Configuration
class BookaroSecurityConfiguration extends WebSecurityConfigurerAdapter {
// ...
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("marek@example.org")
.password("{noop}xxx")
.roles("USER")
.and()
.withUser("admin")
.password("{noop}xxx")
.roles("ADMIN");
}
}
Za pomoc膮 obiektu AuthenticationManagerBuilder
mo偶emy zdefiniowa膰 jakich u偶ytkownik贸w z jakimi rolami chcemy mie膰 w swoim systemie.
W tym wypadku dodaj臋 dw贸ch u偶ytkownik贸w:
marek@example.org
z has艂emxxx
i rol膮USER
,admin
z has艂emxxx
i rol膮ADMIN
.
Zapis .password("{noop}xxx")
oznacza, 偶e nie chc臋 korzysta膰 z 偶adnego (noop => no-operation) algorytmu szyfruj膮cego has艂a. St膮d przy pr贸bie dost臋pu do endpoint贸w w Basic Auth b臋d臋 przekazywa艂 w艂a艣nie xxx
jako has艂o.
Zabezpieczanie po roli
Skoro mamy ju偶 u偶ytkownik贸w z konkretnymi rolami, to mo偶emy je wykorzysta膰 do zabezpieczenia dost臋pu do konkretnych endpoint贸w w aplikacji. Mo偶emy to osi膮gn膮膰 korzystaj膮c z adnotacji @Secured
.
@RestController
@RequestMapping("/admin")
class AdminController {
@Secured("ROLE_ADMIN")
@PostMapping("/data")
public void initialize() {
// ...
}
}
@RestController
@RequestMapping("/orders")
class OrdersController {
@Secured({"ROLE_ADMIN", "ROLE_USER"})
@GetMapping
public ResponseEntity<Order> getOrders() {
// ...
}
}
Do endpointu /admin
b臋dzie mia艂 dost臋p tylko administrator, a do endpointu /orders
zar贸wno administrator jak i zwyk艂y, uwierzytelniony u偶ytkownik. Osoba anonimowa nie b臋dzie mog艂a uzyska膰 odpowiedzi z systemu.
Aby adnotacja @Secured
zadzia艂a艂a, potrzeba j膮 explicite w艂膮czy膰 w naszej aplikacji za pomoc膮 @EnableGlobalMethodSecurity(securedEnabled = true)
.
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
class BookaroSecurityConfiguration extends WebSecurityConfigurerAdapter {
// ...
}
Gotowe!
Twoja aplikacja jest zabezpieczona, wybrane endpointy s膮 schowane za Security, konta zdefiniowane i odpowiednie role przypisane do odpowiednich operacji w aplikacji. W tej chwili dost臋p do systemu jest o wiele lepiej chroniony ni偶 wcze艣niej.
Wersja wideo
Temat poruszali艣my podczas webinaru w ramach Sztuka Kodu Live, kt贸rego nagranie mo偶esz obejrze膰 poni偶ej.
![]()