Spring Security 6 ja JWT-todennus · Oppitunti

Tietokantapohjaisen käyttäjähallinnan integrointi

Integroikaa Spring Security tietokantaan tallennettujen käyttäjien hallintaa ja todentamista varten.

Oppitunti 3/411 vaihetta

Tietokantapohjaisen käyttäjähallinnan integrointi on ilmainen Spring Security 6 ja JWT-todennus-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Spring Security 6 ja JWT-todennus-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Spring Security 6 ja JWT-todennus-kurssilla on yhteensä 4 oppituntia.

Tietokanta käyttäjien hallintaan

Tervetuloa! Tähän asti olemme käyttäneet muistissa olevia käyttäjiä. Tosielämän sovellusten on kuitenkin tallennettava käyttäjätiedot pysyvästi. Tähän tarvitaan tietokantoja!

Tässä oppitunnissa opitte yhdistämään Spring Securityn tietokantaan sovelluksen käyttäjien hallintaa ja todentamista varten.

Miksi käyttää tietokantaa?

Käyttäjien tallentaminen tietokantaan tarjoaa useita tärkeitä etuja:

  • Pysyvyys: Käyttäjätiedot eivät katoa sovelluksen uudelleenkäynnistyksen yhteydessä.
  • Skaalautuvuus: Suuren käyttäjämäärän hallinta on helppoa.
  • Joustavuus: Voitte tallentaa käyttäjille lisätietoja (esimerkiksi sähköpostiosoitteen, roolit ja profiilitiedot).
  • Keskitetty hallinta: Kaikille käyttäjätiedoille on yksi totuuden lähde.

Käyttäjätaulukon perusteet

Ensin tarvitsemme tietokantataulukon käyttäjien tallentamista varten. Yksinkertaiset users- ja authorities-taulukot (rooleja varten) voisivat näyttää tältä:

Näissä taulukoissa on yleensä vähintään käyttäjänimi, salasana ja käyttäjän ”enabled”-tila sekä käyttöoikeuksia varten käyttäjänimi ja valtuutus (rooli).

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)
);

Mukautettu UserDetailsService

Muistattehan, että UserDetailsService on Spring Securityn käyttämä keskeinen rajapinta käyttäjätietojen hakemiseen. Tietokantaintegraatiota varten luomme toteutuksen tai käytämme toteutusta, joka hakee käyttäjätiedot tietokannasta.

Tämä palvelu muodostaa haettujen tietojen perusteella UserDetails-olion, joka sisältää käyttäjänimen, salasanan ja roolit.

package org.springframework.security.core.userdetails;

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

JdbcUserDetailsManagerin käyttäminen

Spring Security tarjoaa JdbcUserDetailsManager-komponentin, joka on kätevä sisäänrakennettu UserDetailsService-rajapinnan toteutus. Se käyttää JDBC:tä (Java Database Connectivity) tietokannan käsittelyyn.

Se odottaa toimiakseen tietynlaista taulukkorakennetta, kuten aiemmin esitettyä. Teidän tarvitsee vain välittää sille 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;
  }
}

Salasanojen turvallinen tallennus

Salasanoja tietokantaan tallennettaessa on ehdottoman tärkeää, ettei niitä koskaan tallenneta selväkielisinä. Käyttäkää aina Password Encoder -komponenttia niiden turvalliseen tiivistämiseen.

BCryptPasswordEncoder on suosittu ja vankka vaihtoehto, joka tarjoaa salasanoille vahvan yksisuuntaisen tiivistyksen.

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

Todentamisen kytkeminen

Integraation viimeistelemiseksi Spring Securitylle on ilmoitettava, että sen tulee käyttää tietokantaan perustuvaa UserDetailsService-palvelua ja valittua PasswordEncoder-komponenttia.

Tämä tehdään yleensä määrittämällä SecurityFilterChain, jossa nämä komponentit asetetaan nimenomaisesti todentamista varten.

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

Täydellinen tietokantatodennuksen esimerkki

Tässä on kokonainen suoritettava Spring Boot -sovellus, joka käyttää muistissa toimivaa H2-tietokantaa, JdbcUserDetailsManager-komponenttia ja BCryptPasswordEncoder-komponenttia. Se luo myös muutaman alkuperäisen käyttäjän.

Suorittakaa sovellus ja yrittäkää sitten käyttää osoitetta /hello. Teitä pyydetään kirjautumaan tunnuksilla ”user”/”password” tai ”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();
    }
  }
}

Tietokantatodennuksen testaaminen

Kun sovellus on käynnissä, avatkaa selain ja siirtykää suojattuun päätepisteeseen (esimerkiksi esimerkkimme /hello-osoitteeseen).

Teidät pitäisi ohjata kirjautumissivulle. Kokeilkaa kirjautumista tietokantaan lisätyillä tunnuksilla:

  • Käyttäjänimi: user, Salasana: password
  • Käyttäjänimi: admin, Salasana: adminpass

Onnistunut kirjautuminen tarkoittaa, että tietokantaintegraatio toimii!

Tietokantatodennuksen tarkistus

Mikä Spring Securityn komponentti on välttämätön käyttäjätietojen lataamiseen tietokannasta?

Kertaus ja seuraavat vaiheet

Hienoa työtä! Olette oppineet yhdistämään Spring Securityn tietokantaan.

  • Ymmärsimme tietokantaan perustuvan käyttäjienhallinnan hyödyt.
  • Tutustuimme käyttäjätaulukoiden perusrakenteisiin.
  • Näimme, miten UserDetailsService-palvelua (erityisesti JdbcUserDetailsManager-komponenttia) ja PasswordEncoder-komponenttia käytetään tietokannan kanssa.
  • Määritimme Spring Securityn käyttämään näitä komponentteja.

Tämä on tärkeä perusta vankkojen ja turvallisten sovellusten rakentamiselle. Seuraavaksi perehdytte tarkemmin valtuutukseen, jolla hallitaan todennettujen käyttäjien toimia!

Aloita maksutta

Opi Java tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
12
Oppitunnit
48

Usein kysytyt kysymykset

Onko oppitunti ”Tietokantapohjaisen käyttäjähallinnan integrointi” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Spring Security 6 ja JWT-todennus-oppimispolun 3 oppituntia, myös oppitunnin “Tietokantapohjaisen käyttäjähallinnan integrointi”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Spring Security 6 ja JWT-todennus-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Tietokantapohjaisen käyttäjähallinnan integrointi”?

Integroikaa Spring Security tietokantaan tallennettujen käyttäjien hallintaa ja todentamista varten. Harjoittelet Spring Security 6 ja JWT-todennus-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Spring Security 6 ja JWT-todennus-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Spring Security 6 ja JWT-todennus-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.

Kuinka kauan ”Tietokantapohjaisen käyttäjähallinnan integrointi”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Spring Security 6 ja JWT-todennus-oppitunnilla?

Kyllä. Jokainen Spring Security 6 ja JWT-todennus-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Mukautetun `UserDetailsService`-toteutuksen luominen
  2. Salasanakooderien ymmärtäminen
  3. Tietokantapohjaisen käyttäjähallinnan integrointi
  4. Roolipohjainen valtuutus myönnetyillä oikeuksilla
← Takaisin: Spring Security 6 ja JWT-todennus