知識庫 / Spring / Spring Security RSS 訂閱

Spring Security – 自定義 403 禁止/訪問拒絕頁面

Spring Security
HongKong
5
02:40 PM · Dec 06 ,2025

1. 引言

本文將演示如何在 Spring Security 項目中自定義“訪問被拒絕”頁面。

這可以通過 Spring Security 配置或在 <em >web.xml</em> 文件中的 Web 應用程序配置來實現。

在接下來的部分中,我們將更深入地研究這些選項。

2. 自定義 JSP

當用户嘗試訪問其未擁有權限的角色限制的頁面時,應用程序將返回狀態碼 403,這意味着 訪問被拒絕

為了將 Spring 的 403 狀態響應頁面替換為自定義頁面,首先讓我們創建一個名為 accessDenied.jspJSP 文件:

<body>
<h2>Sorry, you do not have permission to view this page.</h2>

Click <a href="<c:url value="/homepage.html" /> ">here</a>
to go back to the Homepage.
</body>

3. Spring Security 配置

默認情況下,Spring Security 定義了一個 ExceptionTranslationFilter,它處理類型為 AuthenticationExceptionAccessDeniedException 的異常。 後者通過一個名為 accessDeniedHandler 的屬性完成,它使用 AccessDeniedHandlerImpl 類。

為了自定義此行為,使用我們上面創建的自定義頁面,我們需要覆蓋 ExceptionTranslationFilter 類的屬性。 這可以通過 Java 配置或 XML 配置來實現。

3.1. 訪問權限被拒絕頁面

使用 Java,我們可以通過使用 <em>accessDeniedPage()</em><em>accessDeniedHandler()</em> 方法,在配置 <em>HttpSecurity</em> 元素時,自定義 403 錯誤處理流程。

讓我們創建一個認證配置,將“/admin/**” URL 限制為 <em>ADMIN</em> 角色,並將訪問權限被拒絕頁面設置為我們的自定義 <em>accessDenied.jsp</em> 頁面:

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
      // ...
      .and()
      .exceptionHandling().accessDeniedPage("/accessDenied.jsp");
}

讓我們來看一下拒絕訪問頁面的等效 XML 配置:

<http use-expressions="true">
    <access-denied-handler error-page="/accessDenied"/>
 </http>

3.2. 訪問拒絕處理程序

使用訪問拒絕處理程序而不是頁面具有優勢,即我們可以定義在重定向到 403 頁面的前執行自定義邏輯。為此,我們需要創建一個實現 AccessDeniedHandler 接口的類,並覆蓋 handle() 方法。

讓我們創建一個自定義的 AccessDeniedHandler 類,該類記錄每次訪問拒絕嘗試的消息,其中包含嘗試訪問的用户的姓名以及他們嘗試訪問的受保護 URL:

public class CustomAccessDeniedHandler implements AccessDeniedHandler {

    public static final Logger LOG
      = Logger.getLogger(CustomAccessDeniedHandler.class);

    @Override
    public void handle(
      HttpServletRequest request,
      HttpServletResponse response, 
      AccessDeniedException exc) throws IOException, ServletException {
        
        Authentication auth 
          = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null) {
            LOG.warn("User: " + auth.getName() 
              + " attempted to access the protected URL: "
              + request.getRequestURI());
        }

        response.sendRedirect(request.getContextPath() + "/accessDenied");
    }
}

在安全配置中,我們將定義 Bean 並設置自定義 AccessDeniedHandler

@Bean
public AccessDeniedHandler accessDeniedHandler(){
    return new CustomAccessDeniedHandler();
}

//...
.exceptionHandling().accessDeniedHandler(accessDeniedHandler());

如果我們想要使用 XML 配置上面定義的 CustomAccessDeniedHandler 類,配置方式會略有不同:

<bean name="customAccessDeniedHandler" 
  class="com.baeldung.security.CustomAccessDeniedHandler" />

<http use-expressions="true">
    <access-denied-handler ref="customAccessDeniedHandler"/>
</http>

4. 應用配置

通過定義 <em>error-page</em> 標籤,可以在 Web 應用程序的 <em>web.xml</em> 文件中處理“訪問被拒絕”錯誤。 此標籤包含兩個子標籤:<em>error-code</em>,用於指定要攔截的狀態碼,以及 <em>location</em>,用於指定在遇到錯誤碼時用户將被重定向到的 URL。

<error-page>
    <error-code>403</error-code>
    <location>/accessDenied</location>
</error-page>

如果應用程序沒有 web.xml 文件,如 Spring Boot 的情況,Spring 註解尚不提供與 error-page 標籤完全等效的替代方案。根據 Spring 文檔的説明,在這種情況下,推薦的方法是使用 accessDeniedPage()accessDeniedHandler() 方法,這些方法在第 3 節中進行了介紹。

結論

在本文中,我們詳細介紹瞭如何使用自定義 403 頁來處理訪問權限被拒絕錯誤。

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

發佈 評論

Some HTML is okay.