知識庫 / Spring / Spring Security RSS 訂閱

Spring Security Java 配置簡介

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

1. 概述

本教程是 對 Spring Security 配置的介紹,它允許用户在不使用 XML 的情況下輕鬆配置 Spring Security。

Java 配置已於 Spring 3.1 中加入 Spring Framework,並在 Spring 3.2 中擴展,並通過標註帶有 @Configuration 註解的類來定義。

2. Maven 依賴項

為了將 Spring Security 集成到 Spring Boot 應用程序中,我們需要在我們的 pom.xml 中添加 spring-boot-starter-security 依賴項:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

3. 使用 Java 配置進行 Web 安全性

讓我們從一個基本的 Spring Security Java 配置示例開始:

@Configuration
public class SecurityConfig {

  @Bean
  public UserDetailsService inMemoryUserDetailsService(
    PasswordEncoder passwordEncoder) {
    UserDetails user = User.builder()
      .username("user")
      .password(passwordEncoder.encode("password"))
      .roles("USER")
      .build();
    return new InMemoryUserDetailsManager(user);
  }

}

此配置類設置了一個基本基於 Spring Security 的內存中認證機制。

它定義了一個用户,用户名/密碼為 user/password。 此外,它分配了 USER 角色。 我們使用 InMemoryUserDetailsManager,該組件將用户詳細信息存儲在內存中。 此外,我們還需要一個 PasswordEncoder Bean,用於對用户的密碼進行編碼:

@Bean
public PasswordEncoder passwordEncoder() {
    return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}

4. Web 安全性

為了配置我們的授權規則和認證機制,我們發佈一個 SecurityFilterChain Bean:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
      .authorizeHttpRequests((authz) -> authz
        .anyRequest().authenticated())
      .httpBasic(withDefaults());
    return http.build();
}

上述配置確保任何對應用程序的請求都使用 HTTP 基本身份驗證進行認證。

現在,當我們啓動應用程序並導航到 http://localhost:8080/app/ 時,會顯示一個基本身份驗證登錄提示。在輸入用户名“user”和密碼“password”後,服務器會驗證憑據。如果身份驗證成功,我們就可以訪問請求的資源。

5. 登錄表單

通過將 formLogin DSL 調用添加到我們的聲明中,我們可以添加基於瀏覽器的登錄功能和默認登錄頁面。

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
      .authorizeHttpRequests((authz) -> authz
        .anyRequest().authenticated())
      .formLogin(withDefaults())
      .httpBasic(withDefaults());
    return http.build();
}

在啓動時,我們可以看到一個默認頁面已生成:

6. 基於角色的授權

現在,讓我們使用角色對每個 URL 配置簡單的授權:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
      .authorizeHttpRequests((authz) -> authz
        .requestMatchers("/").hasRole("USER")
        .requestMatchers("/admin/**").hasRole("ADMIN")
        .anyRequest().authenticated()
      )
      .formLogin(withDefaults())
      .httpBasic(withDefaults());
    return http.build();
}

這些限制了對根目錄 (/) 的訪問,對於擁有 USER 角色的用户以及擁有 /admin/** 角色的用户,同時任何已認證的用户都可以訪問網站的其他部分。

請注意我們如何使用類型安全的 API 方法 hasRole

7. 登出

與 Spring Security 的許多其他方面一樣,登出也提供了框架強大的默認設置。

默認情況下,登出請求會失效會話,清除所有身份驗證緩存,清除 SecurityContextHolder,並重定向到登錄頁面。

以下是一個簡單的登出配置:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
      // ...
      .logout(withDefaults());
    return http.build();
}

然而,如果我們想要對可用的處理程序進行更精細的控制,以下是一個更完整的實現方案:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http, 
    LogoutSuccessHandler webSecurityUserLogoutHandler)
    throws Exception {
    http
      // ...
      .logout((logout) -> logout
        .logoutSuccessUrl("/")
        .invalidateHttpSession(true)
        .logoutSuccessHandler(webSecurityUserLogoutHandler)
        .deleteCookies("JSESSIONID")
      );
    return http.build();
}

@Bean
public LogoutSuccessHandler webSecurityUserLogoutHandler() {
    return (request, response, authentication) -> {
      System.out.println("User logged out successfully!");
      response.sendRedirect("/app");
    };
}

此配置提供了一個乾淨且安全的註銷流程,同時在處理註銷後操作方面提供了靈活性。

8. 身份驗證

讓我們看看另一種使用 Spring Security 實現身份驗證的方法。

8.1. 內存身份驗證

請回想一下,在最初階段,我們使用了內存配置:

@Bean
public UserDetailsService inMemoryUserDetailsService(
    PasswordEncoder passwordEncoder) {
    UserDetails user = User.builder()
      .username("user")
      .password(passwordEncoder.encode("password"))
      .roles("USER")
      .build();
    UserDetails admin = User.builder()
      .username("admin")
      .password(passwordEncoder.encode("password"))
      .roles("ADMIN")
      .build();
    return new InMemoryUserDetailsManager(user, admin);
}

8.2. JDBC 身份驗證

為了將其遷移到 JDBC,首先,我們在 h2 依賴項添加到我們的 pom.xml 中:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

另外,我們需要在 application.properties 中配置 H2 數據庫:

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
spring.sql.init.schema-locations=classpath:org/springframework/security/core/userdetails/jdbc/users.ddl

這定義了一個我們可以依賴的數據源,用於後續內容:

@Bean
public UserDetailsManager jdbcUserDetailsManager(DataSource dataSource,
    PasswordEncoder passwordEncoder) {
    JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource);
    UserDetails user = User.builder()
      .username("user")
      .password(passwordEncoder.encode("password"))
      .roles("USER")
      .build();
    UserDetails admin = User.builder()
      .username("admin")
      .password(passwordEncoder.encode("password"))
      .roles("ADMIN")
      .build();
    jdbcUserDetailsManager.createUser(user);
    jdbcUserDetailsManager.createUser(admin);
    return jdbcUserDetailsManager;
}

此外,我們需要設置一個嵌入式的 DataSource,該 DataSource 初始化時使用默認的用户模式。

當然,通過以上兩個示例,我們也需要定義 PasswordEncoder Bean,如文檔所述。Spring Security 提供了一個在 org/springframework/security/core/userdetails/jdbc/users.ddl 中。

我們使用 @Profileinmemoryjdbc)來選擇哪些 UserDetailsManager Bean 應該處於活動狀態:

spring.profiles.active=inmemory

9. 結論

在本快速教程中,我們介紹了 Java 配置對於 Spring Security 的基礎知識,並重點展示了最簡單的配置場景的代碼示例。

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

發佈 評論

Some HTML is okay.