Loading

SpringBoot跨域访问

没有引入Spring Secuity的情况

Christopher 2021.10.23


  • CORS 后端 跨域
  • CORS 是一种访问机制,Cross-Origin Resource Sharing,跨域资源共享,通过在服务器端设置相应头,把发起跨域的原始域名添加到 Access-Control-Allow-Origin 中即可。

何为跨域

  • 域,即域名,跨域,即从域名 A 申请访问域名 B 的资源。其需求常发生在前后端分离项目的调试中。

具体实现

  • 添加如下覆写类
package com....; /* 自行添加 */

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class GlobalCorsConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            //重写父类提供的跨域请求处理的接口
            public void addCorsMappings(CorsRegistry registry) {
                /* 添加映射路径 */
                registry.addMapping("/**")
                        /* 放行哪些原始域 */
                        .allowedOriginPatterns("*")
                        /* 是否发送 Cookie 信息 */
                        .allowCredentials(true)
                        /* 放行哪些原始域(请求方式) */
                        .allowedMethods("GET","POST", "PUT", "DELETE")
                        /* 放行哪些原始域(头部信息) */
                        .allowedHeaders("*")
                        /* 暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息) */
                        .exposedHeaders("Header1", "Header2");
            }
        };
    }
}

引入Spring Security

参考一个开源的spring-jwt-demo

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

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

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()
                // 测试用资源,需要验证了的用户才能访问
                .antMatchers("/**").authenticated()
                // 其他都放行了
                .anyRequest().permitAll()
                .and()
                .csrf().disable()
                .cors()
                .and()
                //暴露头部信息
                .headers().addHeaderWriter(new StaticHeadersWriter(Arrays.asList(
                        new Header("Access-control-Allow-Origin","*"),
                        new Header("Access-Control-Expose-Headers","token"))))
                .and()
                .addFilter(new JWTAuthenticationFilter(authenticationManager()))
                .addFilter(new JWTAuthorizationFilter(authenticationManager()))
                // 不需要session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .exceptionHandling().authenticationEntryPoint(new JWTAuthenticationEntryPoint())
                .accessDeniedHandler(new JWTAccessDeniedHandler());
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(List.of("*"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        configuration.setAllowedHeaders(Arrays.asList("*"));
        //暴露头部信息
        configuration.addExposedHeader("token");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

参考资料:

posted @ 2023-09-11 11:35  AmorFati404  阅读(37)  评论(0)    收藏  举报