データベースとのユーザー管理統合
Spring Securityをデータベースと統合し、永続的なデータソースに保存されたユーザーを管理・認証します。
「データベースとのユーザー管理統合」はCoddyKit上の無料Spring Security 6 & JWT Authenticationレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSpring Security 6 & JWT Authentication学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Spring Security 6 & JWT Authenticationコースには全4レッスンが含まれています。
このレッスンの一部はまだ翻訳されておらず、英語で表示されています。
DB for User Management
Welcome! So far, we've used in-memory users. But real applications need to store user data persistently. That's where databases come in!
In this lesson, you'll learn how to integrate Spring Security with a database to manage and authenticate your application's users.
Why Use a Database?
Storing users in a database offers several key benefits:
- Persistence: User data isn't lost when your app restarts.
- Scalability: Easily manage a large number of users.
- Flexibility: Store additional user attributes (e.g., email, roles, profile info).
- Centralized Management: A single source of truth for all user data.
Basic User Table
First, we need a database table to hold our users. A simple users table and an authorities table (for roles) might look like this:
These tables typically contain at least a username, password, and an 'enabled' status for the user, and a username and authority (role) for permissions.
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)
);Custom UserDetailsService
Recall that UserDetailsService is the core interface Spring Security uses to retrieve user details. For database integration, we'll create or use an implementation that fetches user data from our database.
This service builds a UserDetails object (containing username, password, and roles) from the retrieved data.
package org.springframework.security.core.userdetails;
public interface UserDetailsService {
UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException;
}Using JdbcUserDetailsManager
Spring Security provides JdbcUserDetailsManager, a convenient built-in implementation of UserDetailsService that uses JDBC (Java Database Connectivity) to interact with your database.
It expects specific table schemas (like the one shown earlier) to function correctly. You just need to provide it with a 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;
}
}Secure Password Storage
When storing passwords in a database, it's crucial to never store them in plain text. Always use a Password Encoder to hash them securely.
BCryptPasswordEncoder is a popular and robust choice, providing strong, one-way hashing for passwords.
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();
}
}Wiring Authentication
To complete the integration, we need to tell Spring Security to use our database-backed UserDetailsService and the chosen PasswordEncoder.
This is typically done by configuring the SecurityFilterChain, where we explicitly set these components for authentication.
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();
}
}Complete DB Auth Example
Here's a full runnable Spring Boot application that uses an in-memory H2 database, JdbcUserDetailsManager, and BCryptPasswordEncoder. It also creates some initial users.
Run it, then try to access /hello. You'll be prompted to log in with 'user'/'password' or '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();
}
}
}Testing Database Auth
Once your application is running, open your browser and navigate to a secured endpoint (e.g., /hello in our example).
You should be redirected to the login page. Try logging in with the credentials inserted into the database:
- Username:
user, Password:password - Username:
admin, Password:adminpass
Successful login means your database integration is working!
Database Auth Check
Which Spring Security component is essential for loading user data from a database?
Recap & Next Steps
Great job! You've successfully learned how to integrate Spring Security with a database.
- We understood the benefits of database-backed user management.
- We explored basic user table schemas.
- We saw how to use
UserDetailsService(specificallyJdbcUserDetailsManager) and aPasswordEncoderwith a database. - We configured Spring Security to use these components.
This is a foundational step for building robust, secure applications. Next, you'll dive deeper into authorization to control what authenticated users can do!
よくある質問
「データベースとのユーザー管理統合」レッスンは無料ですか?
はい。「データベースとのユーザー管理統合」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Spring Security 6 & JWT Authenticationコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Spring Security 6 & JWT Authenticationコースには全4レッスンが含まれています。
「データベースとのユーザー管理統合」で何を学びますか?
Spring Securityをデータベースと統合し、永続的なデータソースに保存されたユーザーを管理・認証します。 ブラウザで直接実行するハンズオンコードでSpring Security 6 & JWT Authenticationを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Spring Security 6 & JWT Authenticationを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSpring Security 6 & JWT Authenticationは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「データベースとのユーザー管理統合」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSpring Security 6 & JWT Authenticationレッスンでコードを書いて実行できますか?
はい。すべてのSpring Security 6 & JWT Authenticationレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。