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

如何在@PreAuthorize认证失败时重定向至自定义页面?

没问题,这事儿我熟!要搞定@PreAuthorize认证失败后重定向到自定义页面,咱们可以通过Spring Security的AccessDeniedHandler来实现,这是最直接靠谱的方案。下面给你一步步拆解,照着做就行:

解决方案步骤

1. 自定义AccessDeniedHandler

首先写一个类实现Spring Security的AccessDeniedHandler接口,在handle方法里指定重定向的目标页面。这个类就是用来接管“权限不足”时的处理逻辑:

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

public class CustomAccessDeniedHandler implements AccessDeniedHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        // 这里替换成你的自定义错误页面路径,比如/error/403
        response.sendRedirect(request.getContextPath() + "/error/403");
    }
}

2. 配置SecurityFilterChain,替换默认处理逻辑

接下来在Spring Security的配置类里,把咱们自定义的handler配置进去,覆盖掉默认的“权限不足”提示逻辑。别忘了开启方法级安全(@EnableMethodSecurity),这样@PreAuthorize注解才会生效:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.AccessDeniedHandler;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true) // 必须开启这个才能用@PreAuthorize
public class SecurityConfig {

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

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                // 一定要允许访问自定义错误页面,不然重定向时会被再次拦截
                .requestMatchers("/error/**").permitAll()
                .anyRequest().authenticated()
            )
            // 把自定义的handler绑定到异常处理逻辑里
            .exceptionHandling(ex -> ex
                .accessDeniedHandler(customAccessDeniedHandler())
            );

        return http.build();
    }
}

3. 编写错误页面控制器和HTML页面

然后需要一个控制器来映射咱们刚才指定的/error/403路径,返回自定义的HTML页面:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class ErrorController {

    @GetMapping("/error/403")
    public String accessDenied() {
        // 返回视图名称,对应你模板文件夹里的页面,比如用Thymeleaf的话就是templates/error/403.html
        return "error/403";
    }
}

最后创建你的自定义错误页面,比如src/main/resources/templates/error/403.html(假设用Thymeleaf模板引擎),可以加上自己的样式和提示内容:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>权限不足</title>
    <!-- 这里可以加你自己的CSS样式 -->
</head>
<body>
    <div style="text-align: center; margin-top: 100px;">
        <h1>😅 抱歉,您没有访问该资源的权限!</h1>
        <p>请联系管理员获取对应权限,或者返回<a href="/">首页</a></p>
    </div>
</body>
</html>

小提醒

  • 一定要确保自定义错误页面的路径被permitAll()允许,不然重定向的时候会因为未授权再次被拦截,陷入死循环。
  • 如果需要记录权限拦截的日志,可以在CustomAccessDeniedHandler的handle方法里加上日志代码,比如log.error("用户[{}]访问被拒绝: {}", request.getRemoteUser(), accessDeniedException.getMessage())。
  • 如果你用的是其他模板引擎(比如FreeMarker),只需要调整视图对应的页面路径就行,逻辑都是一样的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:42:18