知識庫 / Spring / Spring Security RSS 訂閱

使用 Spring Security 重定向已登錄用户

Spring Security
HongKong
6
12:54 PM · Dec 06 ,2025

1. 概述

網站通常會阻止用户在已登錄狀態下訪問登錄頁面。 常見的做法是將其重定向到另一個頁面,通常是登錄後應用程序的起始點。

在本教程中,我們將探索使用 Spring Security 實施此解決方案的多種方法。

為了更深入地瞭解如何快速實現登錄,我們可以從這篇文章開始。

2. 身份驗證驗證

首先,我們需要一種驗證身份驗證的方法。

換句話説,我們需要從 SecurityContext 中獲取身份驗證詳情,並驗證用户是否已登錄:

private boolean isAuthenticated() {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    if (authentication == null || AnonymousAuthenticationToken.class.
      isAssignableFrom(authentication.getClass())) {
        return false;
    }
    return authentication.isAuthenticated();
}

我們將在此處使用的,在所有負責重定向的組件中。

3. 從登錄控制器重定向

最簡單的方法是定義登錄頁面的端點,在控制器中實現。

我們需要在用户已認證時返回特定的頁面,否則返回登錄頁面。

@GetMapping("/loginUser")
public String getUserLoginPage() {
    if (isAuthenticated()) {
        return "redirect:userMainPage";
    }
    return "loginUser";
}

4. 使用攔截器

通過登錄頁面的 URI 上攔截器,另一種重定向用户的方式是

攔截器會在請求到達控制器之前攔截該請求。因此,我們可以根據身份驗證情況決定是否繼續處理請求,或者阻止請求並返回重定向響應。

如果用户已認證,我們需要修改響應中的兩個內容:

  • 將狀態碼設置為 HttpStatus.SC_TEMPORARY_REDIRECT
  • 添加 Location 標頭,並使用重定向 URL

最後,我們將通過返回 false 來中斷執行鏈:

public class LoginPageInterceptor implements HandlerInterceptor {
    UrlPathHelper urlPathHelper = new UrlPathHelper();
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if ("/loginUser".equals(urlPathHelper.getLookupPathForRequest(request)) && isAuthenticated()) {
            String encodedRedirectURL = response.encodeRedirectURL(
              request.getContextPath() + "/userMainPage");
            response.setStatus(HttpStatus.SC_TEMPORARY_REDIRECT);
            response.setHeader("Location", encodedRedirectURL);

            return false;
        } else {
            return true;
        }
    }

    // isAuthenticated method 
}

我們需要將攔截器添加到 Spring MVC 生命週期中:

@Configuration
public class LoginRedirectMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginPageInterceptor());
    }
}

我們也可以使用 Spring 的基於 XML 模式的配置來實現相同的結果:

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/loginUser"/>
        <bean class="com.baeldung.loginredirect.LoginPageInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

5. 使用過濾器

類似地,我們可以實現一個 Spring 過濾器。

該過濾器可以直接應用於 SecurityContext,利用 Spring Security 的過濾器鏈。因此,它可以在身份驗證創建後立即攔截請求。

讓我們擴展 GenericFilterBean,覆蓋 doFilter 方法,並驗證身份驗證:

public class LoginPageFilter extends GenericFilterBean {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
        HttpServletRequest servletRequest = (HttpServletRequest) request;
        HttpServletResponse servletResponse = (HttpServletResponse) response;

        if (isAuthenticated() && "/loginUser".equals(servletRequest.getRequestURI())) {

            String encodedRedirectURL = ((HttpServletResponse) response).encodeRedirectURL(
              servletRequest.getContextPath() + "/userMainPage");

            servletResponse.setStatus(HttpStatus.SC_TEMPORARY_REDIRECT);
            servletResponse.setHeader("Location", encodedRedirectURL);
        }

        chain.doFilter(servletRequest, servletResponse);
    }
    // isAuthenticated method 
}

我們需要在過濾器鏈中添加過濾器,位於 UsernamePasswordAuthenticationFilter 之後。

此外,我們需要授權登錄頁 URI 的請求,以便為該請求啓用過濾器鏈:

@Configuration
@EnableWebSecurity
public class LoginRedirectSecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.addFilterAfter(new LoginPageFilter(), UsernamePasswordAuthenticationFilter.class)
            .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> 
                          authorizationManagerRequestMatcherRegistry.requestMatchers("/loginUser").permitAll()
        // Other security configuration
    }
}

最後,如果選擇使用XML配置,我們可以為過濾器定義Bean,並將其添加到安全 HTTP 標籤中的過濾器鏈中:

<beans:bean id="loginPageFilter" class="com.baeldung.loginredirect.LoginPageFilter"/>

<security:http pattern="/**" use-expressions="true" auto-config="true">
    <security:intercept-url pattern="/loginUser" access="permitAll"/>
    <security:custom-filter after="BASIC_AUTH_FILTER" ref="loginPageFilter"/>
</security:http>

關於如何為 Spring Security 創建自定義過濾器的快速教程,請參考這裏。

6. 結論

在本教程中,我們探討了多種使用 Spring Security 從登錄頁面重定向已登錄用户的技巧。

另一個可能對您有幫助的教程是“使用 Spring Security 在登錄後重定向到不同頁面”,其中我們學習瞭如何將不同類型的用户重定向到特定的頁面。

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

發佈 評論

Some HTML is okay.