使用hasAnyAuthority登录遇404白标错误,需认证管理器Bean吗?
问题
登录时出现404白标错误,具体场景:
- 在Spring Security安全配置类中,使用
hasAnyAuthority方法指定ROLE_ADMIN、ROLE_USER多个角色限制/signin接口访问时触发错误 - 使用
hasAuthority指定单个角色时功能正常 - 未创建HTML页面,仅通过返回字符串测试接口,但无法正常访问
咨询:是否需要配置Authentication Manager Bean或Authentication Manager Builder Bean?
安全配置类代码
@EnableWebSecurity @Configuration public class WebSecurityConfig { @Bean public UserDetailsService userDetailsService() { return new UserDetailsServiceImpl(); } @Bean AuthenticationProvider authenticationProvider() { DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); authProvider.setUserDetailsService(userDetailsService()); authProvider.setPasswordEncoder(passwordEncoder()); return authProvider; } @Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .cors() .and() .csrf().disable() .authorizeHttpRequests() .antMatchers("/register").permitAll() .and() .authorizeHttpRequests() .antMatchers("/signin").hasAnyAuthority("ROLE_ADMIN", "ROLE_USER") .and() .formLogin() .permitAll() .and() .authenticationProvider(authenticationProvider()); return http.build(); } }
控制器类代码
@RestController public class UserRegistrationController { @Autowired private UserServices userService; @Autowired private PasswordEncoder passwordEncoder; @PostMapping("/register") public ResponseEntity<User> createUser(@Valid @RequestBody User user) throws Throwable { String tempEmailID = user.getEmailId(); String encryptedPassword = passwordEncoder.encode(user.getPassword()); user.setPassword(encryptedPassword); if (tempEmailID != null && !"".equals(tempEmailID)) { User userObject = userService.fetchUserByEmailId(tempEmailID); if (userObject != null) { throw new ResourceNotFoundException("User with " + tempEmailID + " is already exist "); } userService.save(user); } return new ResponseEntity<User>(user, HttpStatus.CREATED); } @GetMapping("/signin") public String loginPage() { return "login sucess"; } }
解答
核心原因
404错误和是否配置Authentication Manager Bean无关,问题出在Spring Security表单登录的默认行为与接口权限配置的冲突:
- 配置
.formLogin().permitAll()后,Spring Security会默认将/login作为登录页面路径。当未认证用户访问被权限拦截的/signin时,会被重定向到/login,但你没有实现该路径的控制器,因此触发404。 - 使用
hasAuthority单个角色时,若测试用户刚好拥有该角色,会直接通过权限校验,不会触发重定向;而hasAnyAuthority场景下,若用户未认证或角色不匹配,就会触发重定向到不存在的/login路径。
解决方法
方案1:适配表单登录路径
如果要让/signin作为登录入口,需在formLogin中指定对应路径:
.formLogin() .loginPage("/signin") // 指定登录页面路径 .loginProcessingUrl("/signin") // 指定登录请求处理路径 .permitAll()
注意:此时/signin接口需要同时支持GET(返回登录提示)和POST(处理登录请求),需调整控制器方法的请求方式。
方案2:改用HTTP Basic认证(适合REST场景)
既然是REST接口测试,无需表单登录页面,可替换为HTTP Basic认证:
// 移除原有的.formLogin().permitAll().and() .httpBasic() .and() .authenticationProvider(authenticationProvider());
未认证用户访问/signin会返回401未授权,而非重定向到不存在的页面。
方案3:优化权限配置逻辑
合并重复的authorizeHttpRequests配置,同时确保用户先完成认证再访问/signin:
.authorizeHttpRequests(auth -> auth .antMatchers("/register").permitAll() .antMatchers("/signin").hasAnyAuthority("ROLE_ADMIN", "ROLE_USER") .anyRequest().authenticated() )
关于Authentication Manager的说明
无需额外配置Authentication Manager Bean,你已配置的AuthenticationProvider会被Spring Security自动用于构建Authentication Manager。只有当你需要手动调用Authentication Manager(比如自定义登录接口)时,才需要显式暴露该Bean:
@Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { return config.getAuthenticationManager(); }
内容的提问来源于stack exchange,提问作者Hello world
相关产品推荐
相关产品推荐

