我在React中有前端,在Spring Boot中有后端,我正在尝试进行REST身份验证。
问题是我得到标头Set-Cookie: JSESSIONID=221DC95570C24409E1F21B1ED954BDA9; Path=/; HttpOnly
,但chrome从未真正设置cookie,因此登录后,当我尝试使用axios调用端点并withCredentials: true
设置时,我得到401,就好像我在尝试未经身份验证即可到达我的后端端点。我读到某个地方从未设置过cookie,因为前端是localhost:3000
。有什么办法解决吗?还是通过Spring配置REST身份验证的更好方法?无需手动进行完全身份验证。
SecurityConfig
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private RESTAuthenticationEntryPoint authenticationEntryPoint;
@Autowired
private RESTAuthenticationFailureHandler authenticationFailureHandler;
@Autowired
private RESTAuthenticationSuccessHandler authenticationSuccessHandler;
@Autowired
private CustomAuthenticationProvider customAuthProvider;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(new CorsFilter(), SessionManagementFilter.class);
http.cors();
http.csrf().disable();
http.authorizeRequests().antMatchers("/api/*/public/**", "/api/security/**", "/api/auth/**").permitAll().anyRequest().authenticated();
http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint).accessDeniedHandler(new CustomAccessDeniedHandler());
http.formLogin().loginProcessingUrl("/api/auth/login").successHandler(authenticationSuccessHandler);
http.formLogin().failureHandler(authenticationFailureHandler);
http.logout().logoutUrl("/api/auth/logout").invalidateHttpSession(true).logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthProvider);
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(ImmutableList.of("http://localhost:3000"));
configuration.setAllowedMethods(ImmutableList.of("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type", "x-csrf-token", "Access-Control-Allow-Credentials"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
WebConfig
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/**").allowedOrigins("http://localhost:3000").allowedMethods("GET", "POST", "OPTIONS", "PUT", "OPTIONS").allowedHeaders("Content-Type",
"X-Requested-With", "accept", "Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", "x-csrf-token")
.exposedHeaders("Access-Control-Allow-Origin", "Access-Control-Allow-Credentials").allowCredentials(true).maxAge(3600);
}
}
还有一个问题,为什么将CORS到处都设置为localhost,但经过身份验证的端点却返回通配符?可能是因为当前正在为他们投掷401吗?
编辑:
Spring日志显示未经身份验证(可以理解)
2019-01-12 21:04:09.281 DEBUG 13320 --- [nio-8091-exec-3] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@64212f9d: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS