XL's妃妃 2023-09-11 14:10 采纳率: 50%
浏览 23

spring security+vue+axios,为什么通过spring security认证成功之后,访问再次发送请求访问受保护资源,浏览器没有自动携带set-cookie?

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)
}

登录成功之后浏览器响应接口:

img


再次发送请求浏览器的请求体:

img

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-09-11 16:26
    关注

    【以下回答由 GPT 生成】

    问题的根本原因是浏览器在进行跨域请求时,需要服务器在响应中设置Access-Control-Allow-Credentials为true,并且设置set-cookie时,还需要设置SameSite属性为None。

    由于您使用的是Spring Security进行认证,所以可以通过添加一个CorsFilter来解决这个问题。下面是一个简单的示例代码:

    @Configuration
    public class CorsConfig {
    
        @Bean
        public CorsFilter corsFilter() {
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            CorsConfiguration corsConfiguration = new CorsConfiguration();
            corsConfiguration.setAllowCredentials(true);
            corsConfiguration.addAllowedOrigin("*");
            corsConfiguration.addAllowedHeader("*");
            corsConfiguration.addAllowedMethod("*");
            corsConfiguration.addExposedHeader("Set-Cookie"); // 添加ExposedHeader,将Set-Cookie暴露给前端
            source.registerCorsConfiguration("/**", corsConfiguration);
            return new CorsFilter(source);
        }
    
    }
    

    请将上述代码添加到您的Spring Boot项目中,并且确保它被正确加载到应用程序中。

    此外,请确保您的浏览器支持SameSite属性的设置,因为不是所有的浏览器都支持该属性。 希望这可以解决您的问题。如果您还有其他问题,请随时向我询问。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 9月11日

悬赏问题

  • ¥15 安装quartus II18.1时弹出此error,怎么解决?
  • ¥15 keil官网下载psn序列号在哪
  • ¥15 想用adb命令做一个通话软件,播放录音
  • ¥30 Pytorch深度学习服务器跑不通问题解决?
  • ¥15 部分客户订单定位有误的问题
  • ¥15 如何在maya程序中利用python编写领子和褶裥的模型的方法
  • ¥15 Bug traq 数据包 大概什么价
  • ¥15 在anaconda上pytorch和paddle paddle下载报错
  • ¥25 自动填写QQ腾讯文档收集表
  • ¥15 DbVisualizer Pro 12.0.7 sql commander光标错位 显示位置与实际不符