Užtikrinkite savo „Spring“ programos saugumą naudodamiesi tvirtomis „Spring Security“ sistemos teikiamomis funkcijomis.

„Spring Security“ sistema apsaugo jūsų programą per autentifikavimą ir autorizavimą. Pagal numatytąją būseną „Spring Security“ užtikrina, kad kiekvienam jūsų taikomosios programos HTTP užklausos keliui (arba puslapiui) reikalingas vieno visuotinio vartotojo autentifikavimas.

Ši sistema taip pat yra labai lanksti. Tai leidžia jums sukurti pritaikytas saugos taisykles kiekvienam HTTP užklausos keliui jūsų programoje, taip pat skirtingiems vartotojams. Taigi, galite pašalinti saugos apribojimą puslapiuose, kuriems nereikia vartotojo leidimo (pvz., pagrindiniame puslapyje). Ir nustatykite konkrečių vartotojų tipų vaidmenis ir įgaliojimus.

Pavasario saugumo pridėjimas prie programos

Yra du būdai, kaip pridėti „Spring Security“ prie programos. Galite pasirinkti jį kaip priklausomybę kurdami naują „Spring Boot“ programą naudojant Spring inicializr, arba pridėkite jį prie savo kūrimo specifikacijos failo priklausomybės skiltyje sugeneravę projektą.

instagram viewer

Jei pasirinkote vieną iš Gradle projekto parinkčių, priklausomybių failas yra statyti.gradle. Tačiau, jei pasirinkote Maven, tada tas failas yra pom.xml.

Tavo statyti.gradle faile turi būti tokia priklausomybė:

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

Nors jūsų pom.xml faile turi būti tokia priklausomybė:


org.springframework.boot
spring-boot-starter-security

Straipsnyje naudotą programos pavyzdį rasite čia GitHub saugykla ir jūs galite nemokamai naudotis pagal MIT licenciją.

„Spring Security“ naudojimas

Pridėję „Spring Security“ priklausomybę prie programos, galite nedelsdami pradėti naudoti sistemą. Tiesiog paleiskite programą, tada eikite į pagrindinį „Spring Boot“ puslapį (arba bet kurį programos puslapį). Pavyzdinė programa naudoja šį pradinį valdiklį, kad valdytų „Spring Boot“ numatytuosius nustatymus Localhost: 8080 prašymas:

package com.springSecurityDemo.controller;

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

@RestController
publicclassWebController{

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

Vykdydami programą pridėję aukščiau nurodytą vieno valdiklio klasę, sukuriamas toks pradinis vaizdas:

Pastebėsite, kad jis automatiškai nukreipia jus į localhost: 8080 / prisijungimas puslapyje ir tai daroma prieš jums leidžiant pasiekti bet kurį kitą programos puslapį. Šiame etape turėsite pateikti numatytąjį vartotojo vardą (kuris yra vartotojas) ir automatiškai sugeneruotą slaptažodį (kurį rasite konsolėje). Konsolė sugeneruos tokią eilutę:

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

Kiekvieną kartą iš naujo paleidus programą automatiškai sugeneruotas slaptažodis pasikeis, tačiau vartotojo vardas išliks toks pat. Įvedę numatytąjį vartotojo vardą ir slaptažodį, būsite nukreipti į atitinkamą programos rodinį.

Pavasario apsaugos pritaikymas

Norėdami tinkinti programos saugą, turėsite nepaisyti numatytosios „Spring Security“ konfigūracijos. Tačiau prieš tai (darant prielaidą, kad jau turite „Spring Web“) jums reikės kelių kitų šios pavyzdinės programos priklausomybių:

  • Pavasario duomenys JPA
  • MySQL JDBC tvarkyklė
  • Čiobrelio lapelis
  • Lombokas

Thymeleaf sistema sukurs skirtingus vaizdus. Lombok padės sumažinti kodą jūsų objektų klasėse. JPA biblioteka ir MySQL tvarkyklė leis naudoti MySQL duomenų bazę su programa, tačiau jūs turite galimybę naudoti bet kurią jums patogią duomenų bazę. Naudojant duomenų bazę, reikia konfigūruoti programos.ypatybės failą pagal išteklių failą.

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

Aukščiau pateiktas konfigūracijos kodas leidžia prisijungti prie vietinės MySQL duomenų bazės, vadinamos pavasario_saugumas, su vartotojo vardu šaknisir slaptažodis (1234). Turėsite atnaujinti šiuos duomenis, kad jie atitiktų jūsų duomenų bazės pavadinimą ir kredencialus.

Pridėję papildomų priklausomybių ir sukūrę duomenų bazę, galite pradėti nuspręsti, kiek rodinių bus jūsų programa. Taip pat turėsite žinoti, kaip atrodo kiekvieno puslapio sauga. Mūsų paraiškos pavyzdyje yra 6 rodiniai:

  • Pagrindinis puslapis
  • Registracijos puslapis
  • Prisijungimo puslapis
  • Atsijungimo puslapis
  • Vartotojo puslapis
  • Klaidos puslapis

Vienintelis rodinys, kuriam reikės vartotojo įgaliojimo, yra vartotojo puslapis. Šis puslapis pasiekiamas tik tiems vartotojams, kurie pirmiausia užsiregistruoja, tada prisijungia prie programos. Be numatytojo „Spring Boot“ paketo, savo programoje turėsite sukurti dar keturis paketus.

Registracijos valdytojo klasė

Valdiklio pakete bus klasės, kurios apdoroja HTTP užklausas. Atsižvelgiant į puslapio funkciją, kiekvieną HTTP užklausą paprastai galite sugrupuoti į vieną valdiklio klasę, kaip yra su WebController klasė. Tačiau registracijos rodinys turi daugiau unikalių funkcijų, todėl jis gali turėti privataus valdiklio klasę:

@Controller
@RequestMapping("/register")
publicclassRegistrationController{
private UserRepository userRepo;
private PasswordEncoder passwordEncoder;

publicRegistrationController( 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";
}
}

The Registracijos valdiklis klasė yra vartai į jūsų programos saugumo aspektą. The @RequestMapping anotacija nurodo užklausos, kurią šis valdiklis apdoros, tipą (užklausas localhost: 8080 / registras).

The @GetMapping anotacija tiesiog nurodo, kad jei paraiška gauna užklausą /register, Registracijos forma() metodas turėtų apdoroti tą užklausą grąžindamas registracijos rodinį.

Lankytojui spustelėjus registracijos mygtuką, tada @PostMapping įsijungia anotacija. The procesasRegistracija() metodas leidžia paskelbti vartotojo duomenis, kuriuos jis gauna iš Registracijos forma klasę į duomenų bazę, naudodami UserRepository klasė. Tačiau prieš išsaugant šiuos duomenis procesasRegistracija() metodas užšifruoja vartotojo slaptažodį naudojant PavasarioPasswordEncoder sąsaja.

Naujų saugos konfigūracijų kūrimas

Nuo Spring 3.1 kūrėjai dabar gali kurti Spring Security konfigūracijas naudodami Java, o tai reiškia klases, o ne XML. Pagrindinis dalykas, kurio reikalauja šios konfigūracijos klasės, yra @Konfigūracija anotacija.

@Configuration
publicclassSecurityConfiguration{
}

The @Konfigūracija anotacija rodo, kad aukščiau nurodyta klasė yra konfigūracijos klasė. Šios klasės suteikia pupelių Pavasario taikymo kontekstas, kuris yra konteineris, kurį Spring naudoja skirtingiems programos komponentams (arba pupelėms) kurti ir valdyti. Pirmoji pupelė Saugumo konfigūracija klasė yra PasswordEncoder pupelė.

@Bean
public PasswordEncoder passwordEncoder(){
 returnnew BCryptPasswordEncoder();
}

The Registracijos valdiklis klasė naudoja PasswordEncoder bean, kad užkoduotų naujus slaptažodžius prieš išsaugant juos duomenų bazėje. Dar viena svarbi pupelė, kurią turėsite pridėti prie Saugumo konfigūracija klasė yra userDetailsService pupelė.

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

The userDetailsService pupa įdarbina Pavasario apsaugaUserDetailsService sąsaja, skirta gauti vartotojo vartotojo vardą ir slaptažodį autentifikavimui kliento prisijungimo sesijos metu. Taigi, kai tik klientas prisijungimo rodinyje spusteli prisijungimo mygtuką, userDetailsService pupelė pradeda judėti.

Per UserRepository, userDetailsService bean įgyja prieigą prie visų esamų klientų duomenų bazėje. Tada ši sąsaja naudoja UserRepository kad surastų vartotoją su atitinkamu vartotojo vardu ir slaptažodžiu, tada pateikia visus šio kliento atributus kaip objektą.

Jei grąžinamas objektas yra klientas, šis klientas įgyja prieigą prie programos. Priešingu atveju puslapis bus automatiškai atnaujintas ir vartotojas galės įvesti galiojančius kredencialus.

Filtro grandinė

Pavasario apsaugaSecurityFilterChain sąsaja yra naudinga taikomųjų programų sąsaja (API) kuris atlieka esminį vaidmenį „Spring Security“ konfigūracijoje. Ši sąsaja veikia su Pavasario apsauga„HttpSecurity“. klasėje, kad sukurtumėte filtravimo grandinę konkrečioms HTTP užklausoms.

@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();
}

The filtro grandinė pupelės aukščiau naudoja SecurityFilterChain API kelioms užduotims atlikti. Pirma, jis naudoja „HttpSecurity“. klasę, kad diktuotų, kad prieigą galėtų pasiekti tik vartotojai, turintys VARTOTOJO vaidmenį localhost: 8080 / vartotojas. Ir vartotojas gauna šį vaidmenį po registracijos, dėka getAuthorities () metodas, kurį įgyvendina kiekvienas naujas kliento objektas.

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

Filtro grandinė leidžia neautentifikuotai pasiekti visus kitus programos URL. The filtro grandinė pupelės taip pat naudoja formLogin() ir Atsijungti() metodai „HttpSecurity“. klasės objektas.

Šie metodai leidžia automatiškai nukreipti vartotoją į konkrečius puslapius, kai jie atlieka užduotį. Taigi vartotojas, įvedęs teisingus kredencialus ir spustelėjęs prisijungimo mygtuką /login puslapis bus automatiškai nukreiptas į /user puslapį.

Galiausiai, filtro grandinė bean sukuria ir grąžina filtrų grandinę, kuri leidžia įgaliotiems vartotojams pasiekti programą. Visos trys pupelės Saugumo konfigūracija klasė dirbkite kartu, kad apsaugotumėte jūsų paraišką.

Tačiau, filtro grandinė bean vaidina svarbesnį vaidmenį diktuojant leidimo lygį kiekviena HTTP užklausa. Kai į programą įtrauksite daugiau puslapių, galite naudoti filtro grandinė bean nustatyti jų saugumo lygį.

Pagrindinis pavasario saugumo pranašumas

„Spring Security“ suteikia jums visišką kontrolę ne tik, kas turi prieigą prie jūsų programos, bet ir prieigos tipą, kurį gali turėti vartotojas (naudodamas vartotojo vaidmenų funkciją). Prieigos kontrolė yra vienas iš svarbiausių bet kurios programos aspektų. Suteikti bendriesiems vartotojams nefiltruotą prieigą prie programos dėl ribotų prieigos kontrolės kliūčių gali pasirodyti brangi klaida.