Spring Security中@Controller跳转HTML页面提示无权限,@RestController功能正常的问题排查
嗨,我来帮你梳理下这个问题——明明@RestController的接口能正常通过白名单访问,但是@Controller跳转页面就提示无权限,咱们一步步来排查根源:
1. 优先检查白名单路径的匹配规则
你在SecurityConfiguration里定义的白名单数组availablePages中,像"page/registration"这类路径缺少开头的斜杠,而你的PageController实际访问路径是/page/registration(@RequestMapping("/page")加上@GetMapping("/registration")拼接而来)。
Spring Security的requestMatchers对路径匹配是严格区分的,不带斜杠的page/registration和带斜杠的/page/registration会被判定为两个完全不同的路径!这就导致你的白名单根本没匹配到页面的真实访问路径,Spring Security自然会拦截请求并提示无权限。
你可以先把白名单里的页面路径改成带斜杠的格式:
private final String[] availablePages = new String[] { "https://fonts.googleapis.com/css?family=Open+Sans:400,700", "/page/registration", // 补上开头的/ "/act/registration", "/page/unregistered", "/act/unregistered", "/api/v1/auth/**", "/rest/registration", "/registration", "/", // 根路径建议明确写成/ };
2. 排查视图加载时的静态资源请求
当你用@Controller返回视图名称(比如return "registration")时,Thymeleaf会自动加载对应的HTML文件,如果页面里引用了静态资源(比如CSS、JS、图片),这些资源的请求路径如果不在白名单里,也可能触发权限拦截(不过你现在是直接访问页面就提示无权限,这个属于次要排查点,但可以提前预防)。
如果你的静态资源放在src/main/resources/static下,比如/css/style.css,记得把静态资源路径也加到白名单:
"/static/**", "/css/**", "/js/**"
3. 验证JWT过滤器是否误拦截了白名单请求
你配置了addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class),要确保JWT过滤器不会处理白名单内的请求。可以在JwtAuthenticationFilter的doFilterInternal方法里加个判断,提前放行白名单路径:
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String path = request.getRequestURI(); // 检查当前路径是否在白名单中,建议把availablePages提取为公共常量复用 AntPathMatcher matcher = new AntPathMatcher(); for (String allowedPath : availablePages) { if (matcher.match(allowedPath, path)) { filterChain.doFilter(request, response); return; } } // 原有JWT校验逻辑... }
4. 开启调试日志定位匹配逻辑
如果上面的方法都没解决问题,可以开启Spring Security的调试日志,查看具体是哪个规则拦截了请求。在application.properties中添加:
logging.level.org.springframework.security=DEBUG
启动项目后访问/page/registration,通过日志就能清楚看到Spring Security对该请求的匹配过程,快速定位到问题所在。
备注:内容来源于stack exchange,提问作者Nikita

