spring security+vue+axios,为什么通过spring security认证成功之后,访问再次发送请求访问受保护资源,浏览器没有自动携带set-cookie?
这是spring security配置代码:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
private final MyUserDetailService myUserDetailService;
public SecurityConfig(MyUserDetailService myUserDetailService) {
this.myUserDetailService = myUserDetailService;
}
@Override
protected void configure(AuthenticationManagerBuilder auth)throws Exception{
auth.userDetailsService(myUserDetailService);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception{
return super.authenticationManagerBean();
}
@Bean
public LoginFilter loginFilter() throws Exception {
LoginFilter loginFilter = new LoginFilter();
loginFilter.setFilterProcessesUrl("/api/doLogin");//指定认证的url
//指定用户名和密码的key
loginFilter.setUsernameParameter("uname");
loginFilter.setPasswordParameter("passwd");
loginFilter.setAuthenticationManager(authenticationManagerBean());
loginFilter.setAuthenticationSuccessHandler((request, response, authentication) -> {
System.out.println(SecurityContextHolder.getContext().getAuthentication());
HashMap<Object, Object> hashMap = new HashMap<>();
hashMap.put("token", "646031654");
hashMap.put("userinfo", authentication.getPrincipal());
AjaxResult ajaxResult = new AjaxResult();
ajaxResult.setResultObj(hashMap);
String valueAsString = new ObjectMapper().writeValueAsString(ajaxResult);
response.setContentType("application/json;charset=UTF-8");
response.addHeader("Access-Control-Allow-Origin", response.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Set-Cookie", "SameSite=None");
response.getWriter().println(valueAsString);
});//认证成功处理
loginFilter.setAuthenticationFailureHandler((request, response, exception) -> {
HashMap<Object, Object> hashMap = new HashMap<>();
hashMap.put("msg", "登陆失败"+exception.getMessage());
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
String valueAsString = new ObjectMapper().writeValueAsString(hashMap);
response.getWriter().println(valueAsString);
});//认证失败处理
return loginFilter;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.exceptionHandling()//认证异常处理
.authenticationEntryPoint((request, response, authException) -> {
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.getWriter().println(new AjaxResult().setMessage("请认证"));
})
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler((request, response, authentication) -> {
HashMap<Object, Object> hashMap = new HashMap<>();
hashMap.put("msg", "操作成功");
hashMap.put("status", "200");
hashMap.put("authentication",authentication.getPrincipal());
response.setContentType("application/json;charset=UTF-8");
String valueAsString = new ObjectMapper().writeValueAsString(hashMap);
response.getWriter().println(valueAsString);
})
.and()
.cors()//跨域处理方案
//.configurationSource(configurationSource())
.and()
.csrf().disable()
.headers()
.httpStrictTransportSecurity().disable()
.referrerPolicy(Customizer.withDefaults())
.contentSecurityPolicy("script-src 'self'");
/**
* At:用某个filter替换过滤器链的某个filter
* Before:放在滤器链的某个filter之前
* After:放在滤器链的某个filter之后
*/
http.addFilterAt(loginFilter(), UsernamePasswordAuthenticationFilter.class);
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
//corsConfiguration.setAllowedOriginPatterns(Arrays.asList("http://.*"));
//corsConfiguration.setAllowCredentials(true);
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
return source;
}
}
这是axios代码:
import axios from "axios";
const http = axios.create({
//通用请求地址前缀
baseURL:'http://127.0.0.1:8011',
//超时时间
timeout:10000,
withCredentials:true,
crossDomain: true
})
前端api
import http from "@/utils/request";
//用户登录
export const userLogin =(data) => {
return http.post('/api/doLogin', data)
}
登录成功之后浏览器响应接口:
再次发送请求浏览器的请求体: