Spring Security 6 og JWT-autentisering · leksjon

Integrasjon av brukerhåndtering med database

Integrer Spring Security med en database for å administrere og autentisere brukere som er lagret i en persistent datakilde.

Leksjon 3 av 411 trinn

Integrasjon av brukerhåndtering med database er en gratis leksjon i Spring Security 6 og JWT-autentisering på CoddyKit. Dette er leksjon 3 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Spring Security 6 og JWT-autentisering, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Spring Security 6 og JWT-autentisering inneholder totalt 4 leksjoner.

Database for brukerhåndtering

Velkommen! Så langt har vi brukt brukere i minnet. Virkelige applikasjoner trenger imidlertid å lagre brukerdata permanent. Det er her databaser kommer inn!

I denne leksjonen lærer du hvordan du integrerer Spring Security med en database for å håndtere og autentisere brukerne i applikasjonen.

Hvorfor bruke en database?

Det gir flere viktige fordeler å lagre brukere i en database:

  • Vedvarende lagring: Brukerdata går ikke tapt når appen starter på nytt.
  • Skalerbarhet: Du kan enkelt håndtere et stort antall brukere.
  • Fleksibilitet: Du kan lagre flere brukerattributter (for eksempel e-postadresse, roller og profilinformasjon).
  • Sentralisert administrasjon: Én felles kilde til sannheten for alle brukerdata.

Enkel brukertabell

Først trenger vi en databasetabell som inneholder brukerne våre. En enkel users-tabell og en authorities-tabell (for roller) kan se slik ut:

Disse tabellene inneholder vanligvis minst et brukernavn, et passord og en «enabled»-status for brukeren, samt et brukernavn og en authority (rolle) for tillatelser.

CREATE TABLE users (
  username VARCHAR(50) NOT NULL PRIMARY KEY,
  password VARCHAR(500) NOT NULL,
  enabled  BOOLEAN NOT NULL
);

CREATE TABLE authorities (
  username VARCHAR(50) NOT NULL,
  authority VARCHAR(50) NOT NULL,
  CONSTRAINT fk_authorities_users FOREIGN KEY (username) REFERENCES users (username)
);

Egendefinert UserDetailsService

Husk at UserDetailsService er kjernegrensesnittet Spring Security bruker for å hente brukerdetaljer. Ved databaseintegrasjon oppretter eller bruker vi en implementasjon som henter brukerdata fra databasen.

Denne tjenesten bygger et UserDetails-objekt (som inneholder brukernavn, passord og roller) fra dataene som er hentet.

package org.springframework.security.core.userdetails;

public interface UserDetailsService {
  UserDetails loadUserByUsername(String username)
      throws UsernameNotFoundException;
}

Bruke JdbcUserDetailsManager

Spring Security tilbyr JdbcUserDetailsManager, en praktisk innebygd implementasjon av UserDetailsService som bruker JDBC (Java Database Connectivity) til å kommunisere med databasen.

Den forventer bestemte tabellskjemaer (som det som ble vist tidligere) for å fungere riktig. Du trenger bare å gi den en DataSource.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import javax.sql.DataSource;

@Configuration
public class UserManagementConfig {

  @Bean
  public UserDetailsService userDetailsService(DataSource dataSource) {
    JdbcUserDetailsManager userDetailsManager = new JdbcUserDetailsManager(dataSource);
    // Custom queries can be set if your schema differs:
    // userDetailsManager.setUsersByUsernameQuery("SELECT ...");
    // userDetailsManager.setAuthoritiesByUsernameQuery("SELECT ...");
    return userDetailsManager;
  }
}

Sikker lagring av passord

Når du lagrer passord i en database, er det svært viktig å aldri lagre dem i klartekst. Bruk alltid en Password Encoder til å hashe dem på en sikker måte.

BCryptPasswordEncoder er et populært og robust valg som gir sterk, enveis hashing av passord.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class PasswordEncoderConfig {

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

Koble sammen autentisering

For å fullføre integrasjonen må vi fortelle Spring Security at den skal bruke vår databasebaserte UserDetailsService og den valgte PasswordEncoder.

Dette gjøres vanligvis ved å konfigurere SecurityFilterChain, der vi angir disse komponentene for autentisering.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

  private final UserDetailsService userDetailsService;
  private final PasswordEncoder passwordEncoder;

  public WebSecurityConfig(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
    this.userDetailsService = userDetailsService;
    this.passwordEncoder = passwordEncoder;
  }

  @Bean
  public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
      .authorizeHttpRequests(authorize -> authorize
        .anyRequest().authenticated()
      )
      .formLogin(form -> form.permitAll())
      .userDetailsService(userDetailsService)
      .passwordEncoder(passwordEncoder);
    return http.build();
  }
}

Komplett eksempel på databaseautentisering

Her er en komplett kjørbar Spring Boot-applikasjon som bruker en H2-database i minnet, JdbcUserDetailsManager og BCryptPasswordEncoder. Den oppretter også noen innledende brukere.

Kjør den, og prøv deretter å åpne /hello. Du blir bedt om å logge inn med «user»/«password» eller «admin»/«adminpass».

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.sql.DataSource;

@SpringBootApplication
@RestController
public class DatabaseAuthApp {

  public static void main(String[] args) {
    SpringApplication.run(DatabaseAuthApp.class, args);
  }

  @GetMapping("/hello")
  public String hello() {
    return "Hello, secured world!";
  }

  @Configuration
  @EnableWebSecurity
  static class WebSecurityConfig {

    // 1. Configure DataSource for H2 in-memory database
    @Bean
    public DataSource dataSource() {
      return new EmbeddedDatabaseBuilder()
          .setType(EmbeddedDatabaseType.H2)
          .addScript("classpath:org/springframework/security/core/userdetails/jdbc/users.ddl")
          .build();
    }

    // 2. Configure JdbcUserDetailsManager to use the DataSource
    @Bean
    public UserDetailsService userDetailsService(DataSource dataSource, PasswordEncoder passwordEncoder) {
      JdbcUserDetailsManager userDetailsManager = new JdbcUserDetailsManager(dataSource);

      // Create initial users if they don't exist
      if (!userDetailsManager.userExists("user")) {
        UserDetails user = User.builder()
            .username("user")
            .password(passwordEncoder.encode("password"))
            .roles("USER")
            .build();
        userDetailsManager.createUser(user);
      }
      if (!userDetailsManager.userExists("admin")) {
        UserDetails admin = User.builder()
            .username("admin")
            .password(passwordEncoder.encode("adminpass"))
            .roles("ADMIN", "USER")
            .build();
        userDetailsManager.createUser(admin);
      }
      return userDetailsManager;
    }

    // 3. Configure PasswordEncoder
    @Bean
    public PasswordEncoder passwordEncoder() {
      return new BCryptPasswordEncoder();
    }

    // 4. Configure SecurityFilterChain
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
      http
        .authorizeHttpRequests(authorize -> authorize
          .requestMatchers("/admin/**").hasRole("ADMIN") // Example role-based access
          .anyRequest().authenticated()
        )
        .formLogin(form -> form
          .permitAll()
        )
        .logout(logout -> logout
          .permitAll()
        )
        .userDetailsService(userDetailsService(dataSource(), passwordEncoder())); // Explicitly set
      return http.build();
    }
  }
}

Teste databaseautentisering

Når applikasjonen kjører, åpner du nettleseren og går til et sikret endepunkt (for eksempel /hello i eksempelet vårt).

Du bør bli omdirigert til innloggingssiden. Prøv å logge inn med legitimasjonen som ble satt inn i databasen:

  • Brukernavn: user, Passord: password
  • Brukernavn: admin, Passord: adminpass

En vellykket innlogging betyr at databaseintegrasjonen fungerer!

Kontroll av databaseautentisering

Hvilken Spring Security-komponent er avgjørende for å laste inn brukerdata fra en database?

Oppsummering og neste steg

Flott jobbet! Du har lært hvordan du integrerer Spring Security med en database.

  • Vi har forstått fordelene ved databasebasert brukerhåndtering.
  • Vi har utforsket grunnleggende skjemaer for brukertabeller.
  • Vi har sett hvordan du bruker UserDetailsService (nærmere bestemt JdbcUserDetailsManager) og en PasswordEncoder med en database.
  • Vi har konfigurert Spring Security til å bruke disse komponentene.

Dette er et grunnleggende steg i byggingen av robuste og sikre applikasjoner. Deretter skal du lære mer om autorisasjon for å kontrollere hva autentiserte brukere kan gjøre!

Gratis å komme i gang

Lær deg Java med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
12
Leksjoner
48

Ofte stilte spørsmål

Er leksjonen «Integrasjon av brukerhåndtering med database» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Spring Security 6 og JWT-autentisering, inkludert «Integrasjon av brukerhåndtering med database», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Spring Security 6 og JWT-autentisering inneholder totalt 4 leksjoner.

Hva lærer jeg i «Integrasjon av brukerhåndtering med database»?

Integrer Spring Security med en database for å administrere og autentisere brukere som er lagret i en persistent datakilde. Du øver på Spring Security 6 og JWT-autentisering med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Spring Security 6 og JWT-autentisering?

Ingen tidligere erfaring er nødvendig. Spring Security 6 og JWT-autentisering på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.

Hvor lang tid tar leksjonen «Integrasjon av brukerhåndtering med database»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Spring Security 6 og JWT-autentisering-leksjonen?

Ja. Alle Spring Security 6 og JWT-autentisering-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Implementere en egendefinert UserDetailsService
  2. Forstå passordkodere
  3. Integrasjon av brukerhåndtering med database
  4. Rollebasert autorisasjon med Granted Authorities
← Tilbake til Spring Security 6 og JWT-autentisering