Garantisci la sicurezza della tua applicazione Spring sfruttando le robuste funzionalità offerte dal framework Spring Security.

Il framework Spring Security protegge la tua applicazione tramite autenticazione e autorizzazione. Nel suo stato predefinito, Spring Security garantisce che ogni percorso (o pagina) di richiesta HTTP nella tua applicazione richieda l'autenticazione di un singolo utente globale.

Questo quadro è anche estremamente flessibile. Ti consente di creare regole di sicurezza personalizzate per ogni percorso di richiesta HTTP nella tua applicazione, così come per i diversi utenti. Pertanto, puoi rimuovere la restrizione di sicurezza sulle pagine che non richiedono l'autorizzazione dell'utente (come una home page). E impostare i ruoli e le autorità di tipi di utenti specifici.

Aggiunta di Spring Security alla tua applicazione

Esistono due modi per aggiungere Spring Security alla tua applicazione. Puoi selezionarlo come dipendenza durante la generazione di una nuova applicazione Spring Boot

instagram viewer
usando Spring initializro aggiungerlo al file delle specifiche di compilazione nella sezione delle dipendenze dopo aver generato il progetto.

Se hai selezionato una delle opzioni del progetto Gradle, il file delle dipendenze è build.gradle. Tuttavia, se hai scelto Maven, quel file lo è pom.xml.

Tuo build.gradle file deve contenere la seguente dipendenza:

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

Mentre la tua pom.xml file deve contenere la seguente dipendenza:


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

L'applicazione di esempio utilizzata nell'articolo è disponibile in questo Deposito GitHub ed è gratuito per l'uso con la licenza MIT.

Utilizzo della sicurezza primaverile

Dopo aver aggiunto la dipendenza Spring Security alla tua applicazione, puoi iniziare a utilizzare immediatamente il framework. Esegui semplicemente la tua applicazione, quindi vai alla home page di Spring Boot (o qualsiasi pagina nella tua applicazione). L'applicazione di esempio utilizza il seguente controller iniziale per controllare l'impostazione predefinita di Spring Boot host locale: 8080 richiesta:

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!";
}
}

L'esecuzione dell'applicazione dopo aver aggiunto la singola classe controller sopra genera la seguente vista iniziale:

Noterai che ti indirizza automaticamente al host locale: 8080/login page e lo fa prima di consentire l'accesso a qualsiasi altra pagina dell'applicazione. A questo punto, dovrai fornire il nome utente predefinito (che è l'utente) e la password generata automaticamente (che troverai nella console). La console genererà una riga come la seguente:

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

Ad ogni riavvio dell'applicazione, la password generata automaticamente cambierà, ma il nome utente rimarrà lo stesso. L'inserimento del nome utente e della password predefiniti ti indirizzerà alla vista appropriata nella tua applicazione.

Personalizzare Spring Security

Per personalizzare la sicurezza dell'applicazione, dovrai ignorare la configurazione predefinita di Spring Security. Ma prima (supponendo che tu abbia già Spring Web) avrai bisogno di molte altre dipendenze per questa applicazione di esempio:

  • Dati primaverili JPA
  • Driver JDBC per MySQL
  • Foglia di timo
  • Lombok

Il framework Thymeleaf genererà viste diverse. Lombok ti aiuterà a ridurre il codice nelle tue classi di oggetti. La libreria JPA e il driver MySQL ti consentiranno di utilizzare un database MySQL con l'applicazione, ma hai la possibilità di utilizzare qualsiasi database con cui ti senti a tuo agio. Utilizzare un database significa configurare il file applicazioni.proprietà file sotto il file delle risorse.

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

Il codice di configurazione sopra consente di connettersi a un database MySQL locale chiamato sicurezza_primavera, con un nome utente di radicee password (1234). Dovrai aggiornare questi dati in modo che corrispondano al nome e alle credenziali del tuo database.

Dopo aver aggiunto le tue dipendenze aggiuntive e aver creato il tuo database, puoi iniziare a decidere quante visualizzazioni avrà la tua applicazione. Dovrai anche sapere com'è la sicurezza per ogni pagina. La nostra applicazione di esempio ha 6 viste:

  • Pagina iniziale
  • Pagina di registrazione
  • Pagina di login
  • Pagina di disconnessione
  • Pagina utente
  • Pagina di errore

L'unica vista che richiederà l'autorizzazione dell'utente è la pagina utente. Questa pagina è accessibile solo agli utenti che prima si registrano e poi accedono all'applicazione. Oltre al pacchetto predefinito di Spring Boot, dovrai creare altri quattro pacchetti nella tua applicazione.

La classe controller di registrazione

Il pacchetto controller conterrà le classi che gestiscono le richieste HTTP. A seconda della funzione di una pagina, di solito puoi raggruppare ogni richiesta HTTP in una classe controller, come nel caso di WebController classe. Tuttavia, la vista di registrazione ha funzioni più uniche, quindi può avere una classe controller privata:

@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";
}
}

IL Controller di registrazione class è un gateway per l'aspetto della sicurezza della tua applicazione. IL @RequestMapping L'annotazione specifica il tipo di richiesta che questo controller gestirà (richieste a host locale: 8080/registro).

IL @GetMapping L'annotazione indica semplicemente che se l'applicazione riceve una richiesta di /register, IL Modulo di registrazione() Il metodo dovrebbe gestire tale richiesta restituendo la visualizzazione della registrazione.

Dopo che un visitatore fa clic sul pulsante di registrazione, quindi il file @PostMapping entra in gioco l'annotazione. IL processoRegistrazione() Il metodo ti consente di pubblicare i dati utente che ottiene dal file Modulo di registrazione class al database, utilizzando il Archivio utente classe. Ma prima di memorizzare questi dati, il file processoRegistrazione() metodo crittografa la password dell'utente utilizzando Di primaveraCodificatore password interfaccia.

Creazione di nuove configurazioni di sicurezza

Dalla primavera 3.1, gli sviluppatori possono ora creare configurazioni per Spring Security utilizzando Java, il che significa classi invece di XML. La cosa principale richiesta da queste classi di configurazione è il file @Configurazione annotazione.

@Configuration
publicclassSecurityConfiguration{
}

IL @Configurazione l'annotazione indica che la classe precedente è una classe di configurazione. Queste classi forniscono i bean al Contesto applicativo primaverile, che è un contenitore che Spring utilizza per creare e gestire i diversi componenti (o bean) di un'applicazione. Il primo fagiolo nel SecurityConfiguration la classe è la passwordEncoder fagiolo.

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

IL Controller di registrazione la classe usa il passwordEncoder bean per codificare le nuove password prima di salvarle nel database. Un altro fagiolo importante che dovrai aggiungere al file SecurityConfiguration la classe è la userDetailsService fagiolo.

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

IL userDetailsService fagiolo impiega Sicurezza di primaveraUserDetailsService interfaccia per recuperare il nome utente e la password di un utente per l'autenticazione, durante la sessione di accesso di un cliente. Quindi, non appena un cliente fa clic sul pulsante di accesso nella vista di accesso, il file userDetailsService il fagiolo si mette in moto.

Tramite la Archivio utente, IL userDetailsService bean ottiene l'accesso a tutti i clienti esistenti nel database. Questa interfaccia utilizza quindi il file Archivio utente per individuare un utente con nome utente e password corrispondenti, quindi restituisce tutti gli attributi di questo cliente come oggetto.

Se l'oggetto restituito è un cliente, questo cliente ottiene l'accesso all'applicazione. In caso contrario, la pagina si aggiornerà automaticamente consentendo all'utente di inserire credenziali valide.

La catena del filtro

Sicurezza di primaveraSecurityFilterChain l'interfaccia è utile interfaccia di programmazione dell'applicazione (API) che svolge un ruolo essenziale nella configurazione Spring Security. Questa interfaccia funziona con Sicurezza di primaveraHttpSecurity class per creare una catena di filtri per richieste HTTP specifiche.

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

IL filtroCatena fagiolo sopra utilizza il SecurityFilterChain API per eseguire diverse attività. In primo luogo, utilizza il HttpSecurity class per imporre l'accesso solo agli utenti che hanno il ruolo di USER host locale: 8080/utente. E un utente ottiene questo ruolo dopo la registrazione, grazie al getAutorità() metodo implementato da ogni nuovo oggetto cliente.

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

La catena di filtri consente l'accesso non autenticato a tutti gli altri URL nell'applicazione. IL filtroCatena fagiolo utilizza anche il formAccesso() E disconnettersi() metodi del HttpSecurity oggetto di classe.

Questi metodi consentono di indirizzare automaticamente un utente a pagine specifiche dopo aver eseguito un'attività. Pertanto, un utente che immette le credenziali corrette e fa clic sul pulsante di accesso in /login la pagina verrà automaticamente indirizzata al /user pagina.

Infine il filtroCatena bean compila e restituisce la catena di filtri, che consente agli utenti autorizzati di accedere all'applicazione. Tutti e tre i fagioli in SecurityConfiguration class lavorano insieme per proteggere la tua applicazione.

comunque, il filtroCatena bean svolge il ruolo più significativo di dettare il livello di autorizzazione per ogni richiesta HTTP. Quando inizi ad aggiungere più pagine alla tua applicazione, puoi utilizzare il file filtroCatena bean per impostare il loro livello di sicurezza.

Il principale vantaggio di Spring Security

Spring Security ti dà il controllo completo non solo su chi ha accesso alla tua applicazione, ma anche sul tipo di accesso che un utente può avere (tramite la sua funzione ruoli utente). Il controllo degli accessi è uno degli aspetti più importanti di qualsiasi applicazione. Concedere agli utenti generici l'accesso non filtrato alla tua applicazione a causa delle limitate barriere di controllo degli accessi potrebbe rivelarsi un errore costoso.