Contents

Jak zabezpieczyć swoją wiosenną aplikację za pomocą Spring Security

Spring Security to skuteczny sposób zabezpieczania aplikacji poprzez procesy uwierzytelniania i autoryzacji. Domyślnie ta struktura wymaga, aby każdy pojedynczy adres URL lub strona internetowa w aplikacji była dostępna za pomocą poświadczeń pojedynczego, rozpoznawanego na całym świecie użytkownika końcowego.

Zaproponowane podejście wykazuje wyjątkową zdolność adaptacji. Umożliwia sformułowanie dostosowanych przepisów bezpieczeństwa dla każdej indywidualnej trasy żądania HTTP w ramach programu, wraz z różnymi użytkownikami końcowymi. W związku z tym możliwe staje się wyeliminowanie ograniczeń bezpieczeństwa nałożonych na strony internetowe, które nie wymagają uwierzytelniania użytkownika, takie jak strona główna. Ponadto metoda ta pozwala na określenie przypisań ról i poziomów uprawnień dla poszczególnych kategorii użytkowników.

Dodanie zabezpieczenia Spring do Twojej aplikacji

Podczas włączania Spring Security do istniejącej lub nowo tworzonej aplikacji Spring Boot istnieją dwie podstawowe metody implementacji. Pierwszy polega na wybraniu integracji podczas procesu generowania świeżego projektu Spring Boot z wykorzystaniem platformy Spring Initializr. Alternatywnie, można zdecydować się na włączenie go do specyfikacji kompilacji projektu, dodając go do listy zależności we wspomnianym dokumencie po utworzeniu projektu.

Pliki konfiguracyjne dla projektów Gradle są identyfikowane jako build.gradle po wybraniu za pomocą pierwszej opcji, podczas gdy te projekty inMaven są oznaczone jako daspom.xml.

Twój plik build.gradle powinien zawierać określoną zależność, jak opisano poniżej:

 dependencies {
      implementation 'org.springframework.boot:spring-boot-starter-security'
} 

Oczekuje się, że wspomniany wyżej plik XML portfela będzie zawierał określone zależności, które przedstawiono w następujący sposób:

 <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
</dependency> 

Dostęp do dostarczonej przykładowej aplikacji można uzyskać za pośrednictwem repozytorium GitHub, które oferuje ją bezpłatnie na warunkach licencji MIT, umożliwiając użytkownikom korzystanie z niej zgodnie z określonymi warunkami.

Korzystanie z zabezpieczeń Spring

Po włączeniu modułu Spring Security do swojego projektu jesteś teraz przygotowany do bezzwłocznego wdrożenia jego funkcjonalności. Aby to zademonstrować, po prostu uruchom program i skieruj przeglądarkę na oficjalną stronę Spring Boot lub dowolną wyznaczoną stronę w Twojej własnej aplikacji. Podany przykład wykorzystuje główny kontroler, który zarządza standardową obsługą żądań przychodzących kierowanych do wstępnie skonfigurowanego adresu URL http://localhost:8080.

 package com.springSecurityDemo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class WebController {
   
     @GetMapping("/")
      public String home() {
           return "Welcome!";
      }
} 

Wspomniana aplikacja, po włączeniu wspomnianej klasy samotnego kontrolera, daje początkową perspektywę w następujący sposób:

/pl/images/spring-security-app-default-login-page.jpg

Po uzyskaniu dostępu do aplikacji po raz pierwszy zostaniesz przekierowany na stronę localhost:8080/login. Przed uzyskaniem dostępu do jakiejkolwiek innej części programu, użytkownik musi wprowadzić predefiniowaną nazwę użytkownika, którą jest „użytkownik”, wraz z losowo utworzonym hasłem, które można znaleźć w wierszu poleceń. Wiersz polecenia generuje komunikat podobny do poniższego przykładu:

 Using generated security password: c4070465-4c65-4e72-8c3f-3800e631ba81 

Przy kolejnych restartach aplikacji, automatycznie wygenerowane hasło ulegnie zmianie; jednakże nazwa użytkownika pozostaje niezmieniona. Wpisanie predefiniowanej nazwy użytkownika i hasła powoduje przekierowanie do odpowiedniego interfejsu w aplikacji.

Dostosowywanie zabezpieczeń Springa

Aby dostosować zabezpieczenia Twojej aplikacji do konkretnych wymagań, konieczna jest modyfikacja domyślnej konfiguracji dostarczanej przez Spring Security. Jednak zanim to zrobisz, zakładając, że masz już skonfigurowaną podstawową aplikację internetową przy użyciu Springa, istnieje kilka dodatkowych warunków wstępnych, które muszą zostać spełnione, aby wykorzystać ten konkretny przykład:

⭐Wiosenne dane WZP

⭐Sterownik MySQL JDBC

⭐Liść Tymianku

⭐Lombok

Wykorzystanie frameworka Thymeleaf umożliwia generowanie wielu perspektyw, podczas gdy Lombok usprawnia proces kodowania w obiektowych strukturach klas. Ponadto integracja z biblioteką JPA i sterownikiem MySQL ułatwia interakcję z bazą danych MySQL, chociaż według uznania użytkownika można również zastosować alternatywne bazy danych. Aby skonfigurować takie interakcje, konieczne jest dostosowanie ustawień konfiguracyjnych znajdujących się w pliku application.properties, który znajduje się w katalogu zasobów.

 spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/spring_security
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.jpa.hibernate.ddl-auto=update 

W celu nawiązania połączenia z lokalną instancją MySQL oznaczoną jako „spring\_security” z wykorzystaniem nazwy użytkownika „root” i hasła „(1234)” konieczne jest prawidłowe skonfigurowanie dostarczonego kodu konfiguracyjnego poprzez aktualizację odpowiednie informacje, aby zapewnić kompatybilność z konkretną konfiguracją bazy danych.

Po dodaniu niezbędnych zależności i utworzeniu bazy danych możesz przystąpić do określania liczby perspektyw, które obejmie Twoja aplikacja. Ponadto ważne jest, aby wziąć pod uwagę środki bezpieczeństwa stosowane dla każdego punktu widzenia. W naszym ilustracyjnym przykładzie aplikacja zawiera sześć różnych punktów obserwacyjnych.

⭐Strona główna

⭐Strona rejestracji

⭐Strona logowania

⭐Strona wylogowania

⭐Strona użytkownika

⭐Strona błędu

Aby użytkownik mógł uzyskać dostęp do swoich danych osobowych na „stronie użytkownika”, musi najpierw zarejestrować się i zalogować do aplikacji. Tylko ci, którzy się zarejestrowali, mają pozwolenie na przeglądanie tej strony. Ponadto konieczne jest ustanowienie dodatkowych czterech pakietów w ramach aplikacji poza tym, co zapewnia standardowa oferta Spring Boot.

Klasa kontrolera rejestracji

Pakiet Controller zawiera klasy odpowiedzialne za przetwarzanie żądań HTTP. Zwykle pojedyncza klasa kontrolera obsługuje żądania odpowiadające funkcjonalności określonej strony internetowej, tak jak w przypadku klasy WebController. Z drugiej strony, RegistrationView wymaga zarządzania odrębnymi funkcjami, co wymaga dedykowanej prywatnej klasy kontrolera.

 @Controller
@RequestMapping("/register")
public class RegistrationController {
       private UserRepository userRepo;
       private PasswordEncoder passwordEncoder;
       
       public RegistrationController( UserRepository userRepo, PasswordEncoder passwordEncoder) {
             this.userRepo = userRepo;
             this.passwordEncoder = passwordEncoder;
       }
       @GetMapping
       public String registerForm() {
             return "registration";
       }
       @PostMapping
       public String processRegistration(RegistrationForm form) {
             userRepo.save(form.toUser(passwordEncoder));
             return "redirect:/login";
       }
} 

RegistrationController służy jako punkt wejścia dla funkcji bezpieczeństwa w naszej aplikacji, obsługując żądania skierowane do localhost:8080/register. Wskazuje na to adnotacja @RequestMapping, która określa konkretny typ żądania, do obsługi którego przeznaczony jest ten kontroler.

Adnotacja @GetMapping oznacza, że ​​gdy aplikacja napotyka żądanie /register , metoda RegistrationForm() jest odpowiedzialna za przetworzenie tego żądania i wyświetlenie odpowiedniego widoku rejestracji.

Gdy odwiedzający kliknie przycisk rejestracji, do gry wchodzi adnotacja @PostMapping. Metoda processRegistration() umożliwia wysyłanie do bazy danych danych użytkownika uzyskanych z klasy RegistrationForm przy użyciu klasy UserRepository. Ale zanim zapisze te dane, metoda processRegistration() szyfruje hasło użytkownika za pomocą Spring’s Interfejs PasswordEncoder.

Tworzenie nowych konfiguracji zabezpieczeń

Wykorzystując wprowadzenie Spring 3.1, programiści mogą teraz zastosować podejście oparte na Javie do konfiguracji Spring Security poprzez wykorzystanie klas, zamiast polegać na konfiguracjach opartych na XML. Niezbędne do tego procesu jest włączenie

 @Configuration
public class SecurityConfiguration {
} 

Adnotacja @Configuration oznacza, że ​​następująca po niej klasa stanowi klasę konfiguracji, która odgrywa zasadniczą rolę w dostarczaniu składników kontekstu aplikacji Springa. Ten kontener służy Springowi do konstruowania i administrowania różnymi elementami (lub składnikami) aplikacji. W klasie SecurityConfiguration podany składnik początkowy jest oznaczony przez oznaczenie passwordEncoder.

 @Bean
public PasswordEncoder passwordEncoder() {
 return new BCryptPasswordEncoder();
} 

RegistrationController polega na bean passwordEncoder do kodowania nowo wygenerowanych haseł przed ich zapisaniem w bazie danych. Ponadto SecurityConfiguration wymaga włączenia komponentu bean userDetailsService do prawidłowego działania.

 @Bean
public UserDetailsService userDetailsService(UserRepository userRepo) {
 return username -> {
   Customer customer = userRepo.findByUsername(username);
     if (customer != null)
           return customer;
     throw new UsernameNotFoundException("Customer '" \+ username \+ "' not found");
 };
} 

Komponent bean userDetailsService wykorzystuje Spring Security interfejs UserDetailsService do pobierania nazwy użytkownika i hasła w celu uwierzytelnienia , podczas sesji logowania klienta. Tak więc, gdy tylko klient kliknie przycisk logowania w widoku logowania, komponent bean userDetailsService uruchamia się.

Dzięki wykorzystaniu interfejsu UserRepository komponent bean userDetailsService uzyskuje dostęp do obszernej kolekcji użytkowników przechowywanych w bazie danych. Następnie interfejs wykorzystuje UserRepository do identyfikacji użytkownika, którego poświadczenia odpowiadają podanej nazwie użytkownika i haśle, po czym pobiera i zwraca wszystkie istotne informacje dotyczące tego konkretnego klienta jako zagregowanej jednostki.

Po pomyślnym uwierzytelnieniu podanych danych uwierzytelniających, jeśli pobrany podmiot odpowiada zarejestrowanemu klientowi, otrzymuje on pozwolenie na korzystanie z funkcji platformy. W przypadku niepowodzenia sprawdzania poprawności i wprowadzenia nieprawidłowej nazwy użytkownika lub hasła interfejs przechodzi bezproblemowe przeładowanie, zapraszając użytkownika końcowego do wprowadzenia prawidłowych danych logowania w celu kolejnej próby.

Łańcuch filtrów

Spring Security Interfejs SecurityFilterChain to użyteczny interfejs programowania aplikacji (API) który odgrywa kluczową rolę w konfiguracji Spring Security. Ten interfejs współpracuje z Spring Security HttpSecurity class, aby utworzyć łańcuch filtrów dla określonych żądań HTTP.

 @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
  http
  .authorizeHttpRequests((authorize) -> authorize
              .requestMatchers("/user").hasAuthority("USER").anyRequest().permitAll())
  .formLogin(formLogin-> formLogin
              .loginPage("/login").defaultSuccessUrl("/user", true))
  .logout(logout-> logout.logoutSuccessUrl("/logout"));
  return http.build();
} 

Dostarczony kod wykorzystuje klasę HttpSecurity w komponencie bean filterChain do egzekwowania środków bezpieczeństwa poprzez ograniczanie dostępu do określonych punktów końcowych na podstawie ról użytkowników. W szczególności konfiguracja HttpSecurity przyznaje dostęp do punktu końcowego /user tylko tym użytkownikom, którzy posiadają rolę „USER”, która jest określana poprzez implementację metody getAuthorities() znajdującej się w każdym nowo utworzonym obiekcie klienta.

 @Override
public Collection<? extends GrantedAuthority> getAuthorities() {
 return Arrays.asList(new SimpleGrantedAuthority("USER"));
}

Łańcuch filtrów umożliwia nieograniczony dostęp do każdego adresu URL w aplikacji dla użytkowników, którzy nie zostali uwierzytelnieni, ponieważ wykorzystuje procedury logowania i wylogowania z formularza, które zapewnia klasa HttpSecurity.

Implementacja tych technik umożliwia bezproblemową nawigację użytkownikom, którzy pomyślnie wykonali akcję. Na przykład po wprowadzeniu prawidłowych danych uwierzytelniających i kliknięciu przycisku „Zaloguj się” na stronie „/login” użytkownik jest bezproblemowo przekierowywany na stronę „/user” bez konieczności dalszej interwencji ze strony użytkownika.

Podsumowując, komponent bean filterChain konstruuje i generuje łańcuch filtrów, umożliwiając uwierzytelnionym użytkownikom końcowym uzyskanie dostępu do platformy oprogramowania. Wspólną funkcją wszystkich trzech komponentów w klasie konfiguracyjnej SecurityConfiguration jest ochrona aplikacji przed nieautoryzowanym dostępem.

Komponent bean filterChain odgrywa kluczową rolę w określaniu poziomu autoryzacji dla każdego przychodzącego żądania HTTP. Jego wpływ wzrasta wraz z dodawaniem do aplikacji dodatkowych stron internetowych, co pozwala komponentowi bean filterChain na ustalenie ich poziomu bezpieczeństwa.

Główna zaleta zabezpieczenia wiosennego

Spring Security zapewnia szeroki wachlarz możliwości regulacji zarówno osób, którym udzielono dostępu, jak i zakresu uprawnień przyznawanych osobom w domenie Twojej aplikacji (wykorzystując solidną listę ról użytkowników). Wdrażanie skutecznych mechanizmów kontroli dostępu należy do nadrzędnych kwestii przy opracowywaniu rozwiązań programistycznych. Zapewnienie nieograniczonego dostępu szerokiemu gronu użytkowników ze względu na niewystarczające środki ograniczające dostęp może nieumyślnie spowodować znaczne wydatki i potencjalne naruszenia bezpieczeństwa.