Spring Security授权失败:调用Admin接口返回403 Forbidden
Spring Boot Admin路径授权403问题排查求助
我的Spring Boot应用调用AdminController的GET请求时返回403(禁止访问)状态码。我需要限制所有/admin/**路径,仅允许数据库中拥有ADMIN权限的用户访问。已经禁用CSRF,但问题仍未解决。
调试日志显示问题与以下内容相关:Failed to authorize filter invocation [GET /admin/allusers] with attributes [hasAuthority('ADMIN')]
日志
2022-09-08 13:56:20.018 DEBUG 21328 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Securing GET /admin/allusers 2022-09-08 13:56:20.026 DEBUG 21328 --- [nio-8080-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext 2022-09-08 13:56:20.026 DEBUG 21328 --- [nio-8080-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext 2022-09-08 13:56:20.042 DEBUG 21328 --- [nio-8080-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor : Failed to authorize filter invocation [GET /admin/allusers] with attributes [hasAuthority('ADMIN')] 2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] o.s.s.w.s.HttpSessionRequestCache : Saved request http://localhost:8080/admin/allusers to session 2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] o.s.s.w.a.Http403ForbiddenEntryPoint : Pre-authenticated entry point called. Rejecting access 2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext 2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext 2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request 2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Securing GET /error 2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext 2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext 2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Secured GET /error 2022-09-08 13:56:20.190 DEBUG 21328 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : Did not store anonymous SecurityContext 2022-09-08 13:56:20.198 DEBUG 21328 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : Did not store anonymous SecurityContext
Security配置类
package com.example.spring_security.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .csrf().disable() .authorizeRequests() .mvcMatchers("/admin/**").hasAuthority("ADMIN") .anyRequest().permitAll(); return http.build(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
UserDetails实现
package com.example.spring_security.security; import com.example.spring_security.entities.User; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import java.util.Collection; import java.util.stream.Collectors; public class SecurityUser implements UserDetails { private final User user; public SecurityUser(User user){ this.user = user; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return user.getAuthorities() .stream() .map(SecurityAuthority::new) .collect(Collectors.toList()); } @Override public String getPassword() { return user.getPassword(); } @Override public String getUsername() { return user.getUsername(); } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } }
UserDetailsService实现
package com.example.spring_security.services; import com.example.spring_security.repositories.UserRepository; import com.example.spring_security.security.SecurityUser; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; @Service public class JpaUserDetailsService implements UserDetailsService { private final UserRepository userRepository; public JpaUserDetailsService(UserRepository userRepository) { this.userRepository = userRepository; } @Override public UserDetails loadUserByUsername(String username) { var u = userRepository.findUserByUsername(username); return u.map(SecurityUser::new) .orElseThrow(() -> new UsernameNotFoundException("Username not found " + username)); } }
GrantedAuthority实现
package com.example.spring_security.security; import com.example.spring_security.entities.Authority; import org.springframework.security.core.GrantedAuthority; public class SecurityAuthority implements GrantedAuthority { private final Authority authority; public SecurityAuthority(Authority authority) { this.authority = authority; } @Override public String getAuthority() { return authority.getName(); } }
请求协助排查该授权失败导致403的问题。
内容的提问来源于stack exchange,提问作者thor
相关产品推荐
相关产品推荐

