You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 2.7.10如何实现不同路径认证的差异化响应?

解决Spring Boot Security差异化认证处理问题

你的问题出在全局配置了HttpStatusEntryPoint,导致所有未认证请求都返回401,覆盖了表单登录默认的重定向逻辑;移除该配置后,所有未认证请求又都会重定向到登录页,包括API请求,不符合需求。要实现API未认证返回401,页面未认证/无权限重定向到/login的效果,需要按以下方式调整配置:

1. 自定义认证入口点(处理未认证请求)

创建自定义类,根据请求路径判断是API还是页面请求,分别返回401或重定向到登录页:

import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {

    private final AuthenticationEntryPoint apiEntryPoint = new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED);
    private final AuthenticationEntryPoint webEntryPoint = new LoginUrlAuthenticationEntryPoint("/login");

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        if (request.getRequestURI().startsWith("/api/")) {
            apiEntryPoint.commence(request, response, authException);
        } else {
            webEntryPoint.commence(request, response, authException);
        }
    }
}

2. 自定义权限拒绝处理器(处理已认证但无权限请求)

针对已登录但没有USER角色的情况,页面请求重定向到登录页,API请求返回403:

import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CustomAccessDeniedHandler implements AccessDeniedHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        if (request.getRequestURI().startsWith("/api/")) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied");
        } else {
            response.sendRedirect("/login");
        }
    }
}

3. 更新SecurityFilterChain配置

在配置中替换为自定义的处理器:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
            .csrf().disable() // API场景建议禁用CSRF,页面场景可保留
            .authorizeHttpRequests(auth -> auth
                    .mvcMatchers("/api/**").authenticated()
                    .mvcMatchers("/design", "/orders").hasRole("USER")
                    .anyRequest().permitAll()
            )
            .exceptionHandling(exceptions -> exceptions
                    .authenticationEntryPoint(new CustomAuthenticationEntryPoint())
                    .accessDeniedHandler(new CustomAccessDeniedHandler())
            )
            .formLogin(form -> form
                    .loginPage("/login")
                    .loginProcessingUrl("/login")
                    .defaultSuccessUrl("/design")
                    .permitAll()
            )
            .logout(logout -> logout
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                    .permitAll()
            );
    return http.build();
}

核心逻辑说明

  • AuthenticationEntryPoint:专门处理未登录的请求,API路径返回401,页面路径重定向到登录页。
  • AccessDeniedHandler:处理已登录但权限不足的情况,API返回403,页面请求跳转到登录页(满足你“未拥有USER角色访问/design、/orders时重定向到/login”的需求)。

内容的提问来源于stack exchange,提问作者tsavaph

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 01:20:37