没有引入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;
}
}
参考资料:
- SpringBoot 实现前后端分离的跨域访问(CORS) - 知乎 (zhihu.com)
- spring-jwt-demo
- SpringBoot 优雅配置跨域多种方式及Spring Security跨域访问配置的坑