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()))
);
}
}
相关文章
BookstoreApiApplication.java
BookstoreApiApplication.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/BookstoreApiApplication.java).
阅读文章 →DataInitializer.java
DataInitializer.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/config/DataInitializer.java).
阅读文章 →SecurityConfig.java
SecurityConfig.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/config/SecurityConfig.java).
阅读文章 →AuthController.java
AuthController.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/controller/AuthController.java).
阅读文章 →BookController.java
BookController.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/controller/BookController.java).
阅读文章 →ApiErrorResponse.java
ApiErrorResponse.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/dto/ApiErrorResponse.java).
阅读文章 →