使用带有axios的Sping Boot 、Spring Security和Vue.js进行验证和校正时出错

jqjz2hbq  于 2023-02-16  发布在  Spring
关注(0)|答案(1)|浏览(107)

我运行的是vue.js 3,带有Vite 4.0.2、axios 0.25.0和Spring启动(启动器2.7.2)。
我已经在spring boot中创建了一个后端,同时使用vue.js3,vite和axios作为UI。现在,我只想用axios调用rest。就在我实现这些函数之前,我用postman和intelliJ http-request测试了rest api。所有这些都是成功的。
正在运行以下安装程序: Spring 开机应用:网址:(其中x在1 - 4之间)。
为了让这个运行,我在stackoverflow这里检查了很多答案,但没有一个带来解决方案,也没有很多研究一般。
下面是代码:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class WebSecurityConfig implements WebMvcConfigurer {

    @Bean
    public UserDetailsService userDetailsService(BCryptPasswordEncoder bCryptPasswordEncoder) {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("user")
                .password(bCryptPasswordEncoder.encode("userPass"))
                .roles("USER")
                .build());

        manager.createUser(User.withUsername("admin")
                .password(bCryptPasswordEncoder.encode("adminPass"))
                .roles("USER", "ADMIN")
                .build());
        return manager;
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        final CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowedHeaders(List.of("Authorization", "Cache-Control", "Content-Type"));
        corsConfiguration.setAllowedOrigins(List.of("*"));
        corsConfiguration.setAllowedMethods(List.of("GET", "POST", "OPTIONS", "PUT", "DELETE"));
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.setExposedHeaders(List.of("Authorization"));

        http.csrf()
                .disable()
                .cors().configurationSource(r -> corsConfiguration)
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.DELETE)
                .hasRole("ADMIN")
                .antMatchers("/api/**")
                .hasAnyRole("ADMIN")
                .antMatchers("/user/**")
                .anonymous()
                .anyRequest()
                .authenticated()
                .and()
                .httpBasic()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);

        return http.build();
    }

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    public void addCorsMappings(final CorsRegistry registry) {
        registry.addMapping("/")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
                .allowCredentials(true);
    }
}

在另一侧,in vue。注:我在allow-origin中添加了 *,只是为了让它工作,我计划稍后使用一个限制性更强的声明。

module.exports = {
    devServer: {
        proxy: {
            '^/api/v1/products/all': {
                target: 'http://localhost:9050/',
                ws: true,
                changeOrigin: true,
                withCredentials: true,
                headers: {
                    Accept: 'application/json',
                    'Access-Control-Allow-Headers': 'Authorization, Cache-Control, Content-Type', // hier hostname:port statt * , Origin, Content-Type, Authorization
                    'Access-Control-Allow-Origin': '*', // hier hostname:port statt *
                    'Access-Control-Allow-Methods': 'GET, POST, OPTIONS, PUT, DELETE',
                    Authorization: 'Basic admin adminPass'
                },
            },
        }
    }
}

最后是vue中的脚本:

const {data, status} = await axios.get<GetProductPojoResponse>(
        'http://localhost:9050/api/v1/products/all',
        {
          headers: {
            Accept: 'application/json',
            'Access-Control-Allow-Headers': 'Authorization, Cache-Control, Content-Type', // hier hostname:port statt * ', Origin, Content-Type, Authorization'
            'Access-Control-Allow-Origin': '*', // hier hostname:port statt *
            'Access-Control-Allow-Methods': 'GET, POST, OPTIONS, PUT, DELETE',
            Authorization: 'Basic admin adminPass',
            withCredentials: true,
          },
        },
    );

    console.log(JSON.stringify(data, null, 4));

    // ?? "response status is: 200"
    console.log('response status is: ', status);

    return data;

我已经设法得到CORS错误与错误401和403相结合,但我不能解释为什么.....

mqkwyuun

mqkwyuun1#

Cors错误通常来自后端。看起来您没有指定要给予哪些链接访问后端的权限。在filterChain()方法的corsConfiguration中,添加类似corsConfiguration.setAllowedOrigins(List.of(“vueJsSiteLinkHereGoesHere”))的内容;
这是我在我的Angular 项目中使用的安全配置。注意,我没有实现WebMvcConfigurer。
此外,请确保控制器类上没有@CrossOrigins注解,因为它将覆盖此处的设置。
我使用jwt进行身份验证,因此您可能需要添加/删除一些头以满足您的需要

package com.example.backend.security;

import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.List;

@EnableWebSecurity
@EnableMethodSecurity()
@Configuration
@RequiredArgsConstructor
public class SecurityConfig {
    private final AppProperties appProps;
    private static final String[] WHITELISTED_URLS = {
            "/auth/**",
    };

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .cors(Customizer.withDefaults()) // by default, use a bean of the name corsConfigurationSource
                .csrf(AbstractHttpConfigurer::disable) // not really needed in REST
                .authorizeHttpRequests((requests) -> requests
                        .requestMatchers(new AntPathRequestMatcher("/h2/**")).permitAll()
                        .requestMatchers(WHITELISTED_URLS).permitAll()
                        .anyRequest().authenticated()
                )
                .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
                .sessionManagement((session) -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                );
        return http.build();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(List.of(appProps.getFrontendSite()));
        configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS"));
        configuration.setAllowedHeaders(List.of("Authorization", "Access-Control-Allow-Origin", "Content-Type",
                "X-Requested-With", "accept", "Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers"));
        configuration.setAllowCredentials(false); // we're using jwt
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

在youtube上看丹·维加的这段视频。他在vue上也有一些东西:https://youtu.be/HRwlT_etr60

相关问题