Spring Security 6升级后登录报POST方法不支持问题咨询
Spring Security 6 迁移后登录请求路由异常问题
今天尝试升级到Spring Security 6,花费一整天调试仍未解决问题。已阅读官方文档、参考各类示例及相关博客文章,但均无效果。
问题详情
迁移前安全配置
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired private DbUserService userService; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").authenticated() .antMatchers("/**").permitAll() .and() .formLogin() .loginPage("/login") .permitAll() .defaultSuccessUrl("/admin") .and() .logout() .permitAll(); } public DaoAuthenticationProvider authProvider() { DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); authProvider.setUserDetailsService(userService); authProvider.setPasswordEncoder(passwordEncoder()); return authProvider; } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(authProvider()); } }
迁移后安全配置
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfiguration { private AuthenticationManager authenticationManager; @Autowired private DbUserService userService; @Bean public SecurityFilterChain formLoginFilterChain(HttpSecurity http) throws Exception { AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class); authenticationManagerBuilder.userDetailsService(userService); authenticationManager = authenticationManagerBuilder.build(); http.authenticationManager(authenticationManager) .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.ALWAYS); http.securityMatchers((matchers) -> matchers.requestMatchers("/admin/**")) .authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated()) .formLogin(Customizer.withDefaults()); return http.build(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public AuthenticationManager authManager(final AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } }
登录异常现象
迁移前可正常登录,现在持续收到错误信息:Method 'POST' is not supported。排查发现,系统尝试调用自定义LoginController中的POST方法,但该控制器仅实现了显示登录页的GET方法:
登录控制器代码
@Controller public class LoginController { @GetMapping("/login") public String login() { return "login"; } }
登录视图代码
<form th:action="@{/login}" method="post"> <div><label> User Name : <input type="text" name="username"/> </label></div> <div><label> Password: <input type="password" name="password"/> </label></div> <div><input type="submit" value="Sign In"/></div> </form>
请问为何现在请求会路由到自定义控制器而非Spring Security内置的登录处理?这是否是Spring Security 6的刻意变更?
解决后的补充信息
问题已通过接受的解决方案修复,且可与/api/端点的第二套安全配置共存。为便于参考,现将该配置贴出:
@Configuration @EnableWebSecurity public class ApiSecurityConfig { @Value("${security.rest.apikey}") private String restApiKey; @Order(2) @Bean public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception { http.securityMatcher("/api/**") .csrf(AbstractHttpConfigurer::disable) .addFilterBefore(apiKeyAuthFilter(), BasicAuthenticationFilter.class) .authorizeHttpRequests(request -> request .requestMatchers("/api/**").authenticated()); return http.build(); } private Filter apiKeyAuthFilter() { return new OncePerRequestFilter() { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String requestApiKey = request.getHeader("X-Api-Key"); if (!restApiKey.equals(requestApiKey)) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return; } Authentication authentication = new UsernamePasswordAuthenticationToken("apiUser", null, new ArrayList<>()); SecurityContextHolder.getContext().setAuthentication(authentication); try { filterChain.doFilter(request, response); } finally { SecurityContextHolder.clearContext(); } } }; } }
内容的提问来源于stack exchange,提问作者mdd
相关产品推荐
相关产品推荐

