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

Spring Security hasAuthority功能异常,登录后返回403错误排查

问题原因分析
  • 权限匹配顺序逻辑错误:Spring Security 会按antMatchers的编写顺序从上到下匹配路径,命中第一条符合的规则后就不再校验后续规则。你同时给/dashboard分别配置了ADMIN和USER的角色要求,USER访问时会先命中第一条需要ADMIN权限的规则,直接被拦截返回403。
  • 角色校验规则不统一:hasRole()方法会自动给传入的角色名拼接ROLE_前缀后再做权限匹配,而你后续的SUPER_ADMIN用了hasAuthority()方法(该方法不会拼接前缀,直接做完全匹配),同时身份认证成功的Handler里判断的是无前缀的角色名,三者规则不统一导致权限校验失败。
  • 路径权限配置冗余:按照需求USER角色登录后只会跳转/pos,不需要访问/dashboard,你额外给USER配置/dashboard权限反而造成了规则冲突。
  • 超级管理员权限规则异常:你把/**需要SUPER_ADMIN权限的规则放在了所有路径规则最后,前面已经限定了大量路径只有ADMIN/USER可以访问,导致SUPER_ADMIN也无法访问这些路径。
修复方案
  • 统一权限校验规则:全部改用hasAuthority()做权限匹配,避免ROLE_前缀的问题
  • 调整路径匹配顺序:细粒度路径规则放在前面,粗粒度规则放在后面,同时给多角色可访问的路径配置多权限校验
  • 移除冗余的USER角色/dashboard权限配置
  • 调整超级管理员的权限规则,支持其访问所有路径
  • 优化登录成功Handler的角色判断逻辑,避免异常角色跳转错误
修复后代码

安全配置类修改

@Override
protected void configure(HttpSecurity http) throws Exception {
    String loginPage = "/login";
    String logoutPage = "/logout";

    http
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
            .and()
        .authorizeRequests()
            .antMatchers(loginPage).permitAll()
            // ADMIN和SUPER_ADMIN都可访问的管理后台路径
            .antMatchers("/dashboard", "/boxes/**", "/manufacturers/**", "/brands/**",
                    "/stocks/**", "/suppliers/**", "/saleinvoices/**", "/purchaseinvoices/**",
                    "/purchases/**", "/sales/**", "/returns/**", "/users/**").hasAnyAuthority("ADMIN","SUPER_ADMIN")
            // USER可访问的路径
            .antMatchers("/stocks/**", "/pos").hasAnyAuthority("USER","SUPER_ADMIN")
            // 剩余所有路径只有SUPER_ADMIN可访问
            .antMatchers("/**").hasAuthority("SUPER_ADMIN")
            .anyRequest().authenticated()
            .and()
        .csrf().disable()
        .formLogin()
            .loginPage(loginPage).permitAll()
            .loginPage("/")
            .failureUrl("/login?error=true")
            .successHandler(authenticationSuccessHandler)
            .usernameParameter("username")
            .passwordParameter("password")
            .and()
        .logout()
            .logoutRequestMatcher(new AntPathRequestMatcher(logoutPage))
            .logoutSuccessUrl(loginPage)
            .and()
        .exceptionHandling();
}

登录成功Handler修改

@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
    Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
    if (roles.contains("USER")) {
        httpServletResponse.sendRedirect("/pos");
    } else if (roles.contains("ADMIN") || roles.contains("SUPER_ADMIN")) {
        httpServletResponse.sendRedirect("/dashboard");
    } else {
        // 无匹配角色跳转登录页
        httpServletResponse.sendRedirect("/login?error=role");
    }
}

注:请确认你的CustomUserDetailsService返回的权限字符串和代码中判断的"ADMIN"、"USER"、"SUPER_ADMIN"完全一致,不一致的话对应修改即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 20:06:01