Spring Security Java 配置簡介

Spring Security
Remote
0
10:45 PM · Nov 29 ,2025

1. 概述

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

Java 配置已添加到 Spring Framework 中在 Spring 3.1 中,並擴展到 Spring Security 中在 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
public PasswordEncoder passwordEncoder() {
    return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}

4. Web 安全

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

@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();
}

在啓動時,我們看到默認頁面已自動生成:

formLogin

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();
}

這限制了對根目錄 (</) 的訪問,對於具有 </>ROLE_USER 角色 的用户,以及對於具有 </>ROLE_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,首先,我們在我們的 pom.xml 中添加 h2 依賴項:

<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 豆,如概述中所述。 Spring Security 在 org/springframework/security/core/userdetails/jdbc/users.ddl 中提供了一個。

我們使用 @Profile (inmemoryjdbc) 來選擇哪些 UserDetailsManager 豆應該處於活動狀態:

spring.profiles.active=inmemory

9. 結論

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

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

發佈 評論

Some HTML is okay.