知識庫 / Spring / Spring Security RSS 訂閱

Spring Security:使用數據庫後端UserDetailsService進行身份驗證

Spring Security
HongKong
10
02:45 PM · Dec 06 ,2025

1. 概述

本文將演示如何為 Spring Security 使用創建自定義數據庫支持的 <em >UserDetailsService</em> 進行身份驗證。

2. 用户詳情服務 (UserDetailsService)

UserDetailsService 接口用於檢索用户相關數據。它包含一個名為 loadUserByUsername() 的方法,可以被覆蓋以自定義查找用户的過程。

它被 DaoAuthenticationProvider 用於在身份驗證過程中加載用户詳情。

3. 用户模型

為了存儲用户,我們將創建一個 User 實體,並將其映射到數據庫表,該表包含以下屬性:

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(nullable = false, unique = true)
    private String username;

    private String password;

    // standard getters and setters
}

4. 檢索用户

為了檢索與用户名關聯的用户,我們將使用 DAO 類並使用 Spring Data 通過擴展 JpaRepository 接口:

public interface UserRepository extends JpaRepository<User, Long> {

    User findByUsername(String username);
}

5. 用户詳情服務 (UserDetailsService)為了提供我們自己的用户服務,我們需要實現 UserDetailsService 接口。

我們將創建一個名為 MyUserDetailsService 的類,並覆蓋接口中的 loadUserByUsername() 方法。

在該方法中,我們使用 DAO 獲取 User 對象,如果存在,則將其包裝成 MyUserPrincipal 對象,該對象實現了 UserDetails 接口,並返回它:

@Service
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException(username);
        }
        return new MyUserPrincipal(user);
    }
}

讓我們定義MyUserPrincipal 類如下:

public class MyUserPrincipal implements UserDetails {
    private User user;

    public MyUserPrincipal(User user) {
        this.user = user;
    }
    //...
}

6. Spring 配置

我們將演示兩種類型的 Spring 配置:XML 配置和基於註解的配置,這對於使用我們的自定義 UserDetailsService 實現是必不可少的。

6.1 註解配置

為了啓用我們自定義的 <em >UserDetailsService</em>,只需將其添加到我們的應用程序上下文作為 Bean 即可。

由於我們已使用 <em >@Service</em> 註解配置了我們的類,應用程序將在組件掃描期間自動檢測並將其創建為 Bean。因此,這裏無需我們做任何其他操作。

或者,我們可以:

  • 使用 `AuthenticationManagerBuilder` 中的 `userDetailsService` 方法配置它
  • 將其設置為自定義 `authenticationProvider` Bean 的屬性,然後使用 `AuthenticationManagerBuilder` 函數注入它

6.2. XML 配置

對於 XML 配置,我們需要定義一個類型為 MyUserDetailsService 的 Bean,並將其注入到 Spring 的 authentication-provider Bean 中:

<bean id="myUserDetailsService" 
  class="org.baeldung.security.MyUserDetailsService"/>

<security:authentication-manager>
    <security:authentication-provider 
      user-service-ref="myUserDetailsService" >
        <security:password-encoder ref="passwordEncoder">
        </security:password-encoder>
    </security:authentication-provider>
</security:authentication-manager>
    
<bean id="passwordEncoder" 
  class="org.springframework.security
  .crypto.bcrypt.BCryptPasswordEncoder">
    <constructor-arg value="11"/>
</bean>

7. 其他基於數據庫的身份驗證選項

AuthenticationManagerBuilder 提供了另一種配置基於 JDBC 的身份驗證的方法,在我們應用程序中。

我們需要使用AuthenticationManagerBuilder.jdbcAuthentication 配置一個DataSource 實例。如果我們的數據庫遵循 Spring User Schema,則默認配置將適合我們。

我們在之前的文章中看到了使用這種方法進行的配置。

JdbcUserDetailsManager 實體,由此配置產生,也實現了UserDetailsService

因此,我們可以得出結論,這種配置更容易實現,尤其當我們使用 Spring Boot 時,Spring Boot 會自動配置DataSource

如果我們需要更高的靈活性,並且需要自定義應用程序如何檢索用户詳細信息,則我們會選擇我們在本教程中遵循的方法。

8. 結論

綜上所述,本文展示瞭如何創建基於 Spring 的自定義 UserDetailsService,並支持持久化數據。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.