知識庫 / Spring / Spring Security RSS 訂閱

使用 Spring Security 安全保障 Jakarta EE 應用

Jakarta EE,Spring Security
HongKong
5
02:25 PM · Dec 06 ,2025

1. 概述

在本快速教程中,我們將探討如何使用 Spring Security 安全地保護 Jakarta EE Web 應用程序。

2. Maven 依賴

讓我們從本教程所需的 Spring Security 依賴項開始:

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>5.7.5</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>5.7.5</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-taglibs</artifactId>
    <version>5.7.5</version>
</dependency>

本教程編寫時,最新版本的 Spring Security 是 5.7.5;如往常一樣,我們可以在 Maven Central 上查看最新版本。

3. 安全配置

接下來,我們需要為現有的 Jakarta EE 應用程序設置安全配置:

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig {

    @Bean
    public InMemoryUserDetailsManager userDetailsService() {
        UserDetails user = User.withUsername("user1")
            .password("{noop}user1Pass")
            .roles("USER")
            .build();
        UserDetails admin = User.withUsername("admin")
            .password("{noop}adminPass")
            .roles("ADMIN")
            .build();
        return new InMemoryUserDetailsManager(user, admin);
    }
}

為了簡化起見,我們實現了一個簡單的內存中認證。用户信息是硬編碼的。

這旨在用於快速原型設計,當不需要完整的持久化機制時。

接下來,讓我們通過添加 SecurityWebApplicationInitializer 類將安全性集成到現有系統中:

public class SecurityWebApplicationInitializer
  extends AbstractSecurityWebApplicationInitializer {

    public SecurityWebApplicationInitializer() {
        super(SpringSecurityConfig.class);
    }
}

此類將確保 SpringSecurityConfig 在應用程序啓動期間加載。 在此階段,我們已經實現了 Spring Security 的基本實現。 通過此實現,Spring Security 將默認要求所有請求和路由進行身份驗證。

4. 配置安全規則

我們可以通過創建 SecurityFilterChain 託管 Bean,進一步自定義 Spring Security:

 @Bean
 public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
     http.csrf()
         .disable()
         .authorizeRequests()
         .antMatchers("/auth/login*")
         .anonymous()
         .antMatchers("/home/admin*")
         .hasRole("ADMIN")
         .anyRequest()
         .authenticated()
         .and()
         .formLogin()
         .loginPage("/auth/login")
         .defaultSuccessUrl("/home", true)
         .failureUrl("/auth/login?error=true")
         .and()
         .logout()
         .logoutSuccessUrl("/auth/login");
     return http.build();
 }

使用 antMatchers() 方法,我們配置 Spring Security 以允許匿名訪問 /auth/login 任何其他請求

4.1. 自定義登錄頁面

使用 formLogin() 方法配置自定義登錄頁面:

http.formLogin()
  .loginPage("/auth/login")

如果未指定,Spring Security 將生成默認登錄頁面在 /login

<html>
<head></head>
<body>
<h1>Login</h1>
<form name='f' action="/auth/login" method='POST'>
    <table>
        <tr>
            <td>User:</td>
            <td><input type='text' name='username' value=''></td>
        </tr>
        <tr>
            <td>Password:</td>
            <td><input type='password' name='password'/></td>
        </tr>
        <tr>
            <td><input name="submit" type="submit" 
              value="submit"/></td>
        </tr>
    </table>
</form>
</body>
</html>
<h3><strong>4.2. 自定義登陸頁面</strong></h3
<p>在成功登錄後,Spring Security會將用户重定向到應用程序的根目錄。我們可以通過指定默認成功URL來覆蓋此行為:</p>
http.formLogin()
  .defaultSuccessUrl("/home", true)

通過將 defaultSuccessUrl() 方法的 alwaysUse 參數設置為 true,用户將始終被重定向到指定的頁面。

如果 alwaysUse 參數未設置或設置為 false,用户將被重定向到他嘗試訪問的上一頁,在提示身份驗證之前。

同樣,我們也可以指定自定義失敗頁面:

http.formLogin()
  .failureUrl("/auth/login?error=true")

4.3. 授權

我們可以通過角色限制對資源的訪問:

http.formLogin()
  .antMatchers("/home/admin*").hasRole("ADMIN")

非管理員用户嘗試訪問 /home/admin 終點時,將會收到“訪問拒絕”錯誤。

我們還可以根據用户的角色在 JSP 頁面上限制數據。這通過使用 <security:authorize> 標籤來實現:

<security:authorize access="hasRole('ADMIN')">
    This text is only visible to an admin
    <br/>
    <a href="<c:url value="/home/admin" />">Admin Page</a>
    <br/>
</security:authorize>

要使用此標籤,我們需要在頁面的頂部包含 Spring Security 標籤庫:

<%@ taglib prefix="security" 
  uri="http://www.springframework.org/security/tags" %>

5. Spring Security XML 配置

我們之前已經探討了在 Java 中配置 Spring Security 的方法。現在,讓我們來看一個等效的 XML 配置。

首先,我們需要在 web/WEB-INF/spring 文件夾中創建一個 security.xml 文件,其中包含我們的 XML 配置。 這樣的 security.xml 配置文件的示例可以在文章末尾找到。

接下來,讓我們配置身份驗證管理器和身份驗證提供者。 為了簡化起見,我們使用硬編碼的簡單用户憑據:

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="user" 
              password="user123" 
              authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>
</authentication-manager>

我們剛才所做的是創建一個用户,該用户具有用户名、密碼和角色。

或者,我們可以使用密碼編碼器配置我們的身份驗證提供程序:

<authentication-manager>
    <authentication-provider>
        <password-encoder hash="sha"/>
        <user-service>
            <user name="user"
              password="d7e6351eaa13189a5a3641bab846c8e8c69ba39f" 
              authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>
</authentication-manager>

我們還可以指定 Spring 的 UserDetailsService 的自定義實現或 Datasource 作為身份驗證提供者。 更多詳細信息請參考 這裏

現在我們已經配置了身份驗證管理器,接下來我們設置安全規則並應用訪問控制:

<http auto-config='true' use-expressions="true">
    <form-login default-target-url="/secure.jsp" />
    <intercept-url pattern="/" access="isAnonymous()" />
    <intercept-url pattern="/index.jsp" access="isAnonymous()" />
    <intercept-url pattern="/secure.jsp" access="hasRole('ROLE_USER')" />
</http>

在上述片段中,我們配置了 HttpSecurity 使用表單登錄,並將 /secure.jsp 設置為登錄成功 URL。我們授予匿名用户對 /index.jsp/ 路徑的訪問權限。 此外,我們指定對 /secure.jsp 的訪問需要身份驗證,並且經過身份驗證的用户至少應具有 ROLE_USER 級別的權限。

http 標籤的 auto-config 屬性設置為 true 會指示 Spring Security 實現默認行為,而無需在配置中覆蓋這些行為。 因此,/login/logout 將分別用於用户登錄和註銷。 還提供了一個默認登錄頁面。

我們可以通過自定義登錄和註銷頁面,以及處理身份驗證成功和失敗的 URL,進一步自定義 form-login 標籤。 Security Namespace appendix 列出了 form-login (和其他) 標籤的所有可能屬性。 某些 IDE 還可以通過按住 ctrl 鍵點擊標籤進行檢查。

最後,為了在應用程序啓動期間加載 security.xml 配置,我們需要將以下定義添加到我們的 web.xml 中:

<context-param>                                                                           
    <param-name>contextConfigLocation</param-name>                                        
    <param-value>                                                                         
      /WEB-INF/spring/*.xml                                                             
    </param-value>                                                                        
</context-param>                                                                          
                                                                                          
<filter>                                                                                  
    <filter-name>springSecurityFilterChain</filter-name>                                  
    <filter-class>
      org.springframework.web.filter.DelegatingFilterProxy</filter-class>     
</filter>                                                                                 
                                                                                          
<filter-mapping>                                                                          
    <filter-name>springSecurityFilterChain</filter-name>                                  
    <url-pattern>/*</url-pattern>                                                         
</filter-mapping>                                                                         
                                                                                          
<listener>                                                                                
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

請注意,在同一 JEE 應用中使用基於 XML 和 Java 的配置可能會導致錯誤。

6. 結論

在本文中,我們學習瞭如何使用 Spring Security 安全地保護 Jakarta EE 應用程序,並演示了基於 Java 和 XML 的配置方法。

我們還討論瞭如何根據用户角色授予或撤銷對特定資源的訪問權限。

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

發佈 評論

Some HTML is okay.