使用Spring Security 在Boot 项目中,实现前后端分离的跨域访问,只需要简单的配置即可。
未使用Security 的Boot 项目
在未使用Spring Security 的Boot 项目中,只需要在 Application.java 中添加如下代码即可
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("PUT", "DELETE", "GET", "POST", "OPTIONS")
.allowedHeaders("*")
.exposedHeaders("access-control-allow-headers",
"access-control-allow-methods",
"access-control-allow-origin",
"access-control-max-age",
"X-Frame-Options")
.allowCredentials(true).maxAge(3600);
}
};
}
或者单独以Config 的形式
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("PUT", "DELETE", "GET", "POST", "OPTIONS")
.allowedHeaders("*")
.exposedHeaders("access-control-allow-headers",
"access-control-allow-methods",
"access-control-allow-origin",
"access-control-max-age",
"X-Frame-Options")
.allowCredentials(true).maxAge(3600);
}
}
使用Security 的情况
使用Security 时,为了让所有接口都支持跨域,以及支持自定义的 请求方式 (GET POST PUT 等)。只需要增加如下配置:
/**
* Security 配置
*
* @author xuefeihu
*/
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(loginAuthenticationProvider);
auth.authenticationProvider(tokenAuthenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
// 开启跨域
.cors().and()
.exceptionHandling()
.authenticationEntryPoint(this.authenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers('/api/login').permitAll()
.and()
.addFilterBefore(buildTokenAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
使用Security开启允许iframe嵌套
使用上面的配置,当前端页面发生嵌套时,会响应如下响应头,从而不可以嵌套页面。
此时只需要禁用 X-Frame-Options 头即可,如下所示:
/**
* Security 配置
*
* @author xuefeihu
*/
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// 开启允许iframe 嵌套
http.headers().frameOptions().disable();
http.csrf().disable()
// 开启跨域
.cors().and()
.exceptionHandling()
.authenticationEntryPoint(this.authenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers('/api/login').permitAll()
.and()
.addFilterBefore(buildTokenAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class);
}
}