Spring Security自定义登录成功后放行页面的问题求助
问题分析与解决方案
你遇到的405错误根源在于Spring Security的formLogin配置与自定义/login接口冲突:formLogin默认会接管/login端点的处理逻辑,当你通过Angular发送POST请求到/login时,Security过滤器会拦截该请求,认为请求方法不被允许,从而返回405状态码。
以下是正确的实现步骤:
1. 调整Spring Security配置
移除formLogin相关配置(因为你使用自定义REST登录接口,而非Security默认的表单登录页面),同时配置CORS支持跨域请求(适配Angular前端),并明确权限规则:
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class Config { @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(10); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.csrf().disable() // 配置CORS,允许Angular前端的跨域请求 .cors(cors -> cors.configurationSource(corsConfigurationSource())) .authorizeRequests() .antMatchers(HttpMethod.POST, "/login").permitAll() // 允许POST请求访问/login .antMatchers("/welcome").hasRole("ADMIN") // /welcome仅允许ADMIN角色访问 .anyRequest().authenticated() // 配置会话管理,保持登录状态以便后续访问受保护资源 .and() .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)); return http.build(); } // 暴露AuthenticationManager,用于自定义登录逻辑中的用户验证 @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception { return authConfig.getAuthenticationManager(); } // CORS配置,根据你的Angular实际端口调整 @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200")); configuration.setAllowedMethods(Arrays.asList("GET", "POST", "OPTIONS")); configuration.setAllowedHeaders(Arrays.asList("Content-Type")); configuration.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } @Bean public InMemoryUserDetailsManager userDetailsManager() { var linda = User.builder() .username("linda") .password(passwordEncoder().encode("pass")) .roles("ADMIN") .build(); return new InMemoryUserDetailsManager(linda); } }
2. 修改LoginController实现正确认证逻辑
使用Spring Security的AuthenticationManager验证用户凭据,并将认证结果存入SecurityContext,确保后续请求能识别用户登录状态:
@RestController public class LoginController { private final AuthenticationManager authenticationManager; // 构造注入AuthenticationManager public LoginController(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } @PostMapping("/login") public ResponseEntity<String> login(@RequestBody User user) { try { // 验证用户名和密码 Authentication authentication = authenticationManager.authenticate( new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()) ); // 将认证信息存入SecurityContext,标记用户已登录 SecurityContextHolder.getContext().setAuthentication(authentication); return ResponseEntity.ok("Access granted"); } catch (BadCredentialsException e) { return ResponseEntity.badRequest().body("Access denied"); } } }
3. 确保User实体类的正确性
User类需要包含username和password的getter方法,以便Spring能正确解析请求体:
public class User { private String username; private String password; // 构造器、getter和setter public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
测试验证
- Angular前端发送POST请求到
/login,携带JSON体:{"username":"linda", "password":"pass"},会返回200 OK。 - 登录成功后,访问
/welcome端点,会返回正常响应(已认证状态)。 - 若登录失败或未登录时访问
/welcome,会返回403 Forbidden。
内容的提问来源于stack exchange,提问作者xRay
相关产品推荐
相关产品推荐

