S SmartDocs
Serie: Springboot java 53 righe · Aggiornato 2026-08-14

CustomUserDetailsService.java

Springboot/bookstore-api/src/main/java/com/example/bookstore/security/CustomUserDetailsService.java

package com.example.bookstore.security;

import com.example.bookstore.entity.User;
import com.example.bookstore.repository.UserRepository;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 自訂的 UserDetailsService——告訴 Spring Security「怎麼載入使用者」。
 *
 * 【呼叫時機】
 *   1. 登入時:AuthenticationManager 用它取得使用者資料後比對密碼。
 *   2. 每次帶 JWT 的請求:JwtAuthenticationFilter 用它載入使用者權限。
 *
 * Spring Security 不關心你的使用者存在哪裡(MySQL?LDAP?記憶體?),
 * 它只認 UserDetailsService 這個介面——我們實作它,從 MySQL 載入。
 */
@Service
public class CustomUserDetailsService implements UserDetailsService {

    private final UserRepository userRepository;

    /** 建構子注入(Constructor Injection):Spring 官方推薦的注入方式 */
    public CustomUserDetailsService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    /**
     * 依帳號載入使用者,並轉換成 Spring Security 認識的 UserDetails 格式。
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        // 1. 從資料庫查詢使用者,查不到就拋出 Spring Security 的標準例外
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("找不到使用者:" + username));

        // 2. 把我們的 User Entity 轉成 Spring Security 內建的 UserDetails 實作
        //    - username:帳號
        //    - password:BCrypt 雜湊值(登入時由 Spring 比對)
        //    - authorities:權限清單(這裡放入角色,如 ROLE_ADMIN)
        return new org.springframework.security.core.userdetails.User(
                user.getUsername(),
                user.getPassword(),
                List.of(new SimpleGrantedAuthority(user.getRole().name()))
        );
    }
}

Articoli correlati

Springboot java EN Aggiornato 2026-08-14

BookstoreApiApplication.java

BookstoreApiApplication.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/BookstoreApiApplication.java).

Leggi l'articolo →
Springboot java EN Aggiornato 2026-08-14

DataInitializer.java

DataInitializer.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/config/DataInitializer.java).

Leggi l'articolo →
Springboot java EN Aggiornato 2026-08-14

SecurityConfig.java

SecurityConfig.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/config/SecurityConfig.java).

Leggi l'articolo →
Springboot java EN Aggiornato 2026-08-14

AuthController.java

AuthController.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/controller/AuthController.java).

Leggi l'articolo →
Springboot java EN Aggiornato 2026-08-14

BookController.java

BookController.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/controller/BookController.java).

Leggi l'articolo →
Springboot java EN Aggiornato 2026-08-14

ApiErrorResponse.java

ApiErrorResponse.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/dto/ApiErrorResponse.java).

Leggi l'articolo →