一. 啟用Spring Security 的CORS支持
1. 普通的跨域
方式1:在接口方法上利用@CrossOrigin注解解決跨域問題
@RestController
public class IndexController {
@CrossOrigin(value = "http://localhost:8082")
@GetMapping("/hello")
public String hello() {
return "get hello";
}
@CrossOrigin(value = "http://localhost:8082")
@PostMapping("/hello")
public String hello2() {
return "post hello";
}
}
方式2:通過實(shí)現(xiàn)WebMvcConfigurer接口來解決跨域問題
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8082")
.allowedMethods("*")
.allowedHeaders("*");
}
}
二. Spring Security環(huán)境下的跨域問題解決
通過上面的配置,我們已經(jīng)解決了Ajax的跨域請求問題,但是這個(gè)案例中也有潛在的威脅存在,常見的就是 CSRF(Cross-site request forgery) 跨站請求偽造。跨站請求偽造也被稱為 one-click attack 或者 session riding,通??s寫為 CSRF 或者 XSRF,是一種挾制用戶在當(dāng)前已登錄的 Web 應(yīng)用程序上執(zhí)行非本意的操作的攻擊方法。
所以為了提高網(wǎng)站的安全性,我在上面Spring Boot項(xiàng)目的基礎(chǔ)之上,添加Spring Security的依賴包,但是暫時(shí)不進(jìn)行任何別的操作。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
2. 解決Spring Security環(huán)境下跨域問題的4種方案
通過實(shí)驗(yàn)可知,如果使用了 Spring Security,上面的跨域配置會(huì)失效,因?yàn)檎埱髸?huì)被 Spring Security 攔截。那么在Spring Security環(huán)境中,如何解決跨域問題呢?這里我們有3種方式可以開啟 Spring Security 對跨域的支持。
2.1 方式一:開啟cors方法
我們在上面的案例之上,編寫一個(gè)SecurityConfig配置類,在configure方法中,利用cors() 開啟Spring Security 對 CORS 的支持:
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.permitAll()
.and()
.formLogin()
.permitAll()
.and()
.httpBasic()
.and()
//支持跨域訪問
.cors()
.and()
.csrf()
.disable();
}
}
2.2 方式二:進(jìn)行全局配置
第二種方式是去除上面的跨域配置,直接在 Spring Security 中做全局配置,如下:
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.permitAll()
.and()
.formLogin()
.permitAll()
.and()
.httpBasic()
.and()
//支持跨域訪問
.cors()
.configurationSource(corsConfigurationSource())
.and()
.csrf()
.disable();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
configuration.setAllowedOrigins(Collections.singletonList("*"));
configuration.setAllowedMethods(Collections.singletonList("*"));
configuration.setAllowedHeaders(Collections.singletonList("*"));
configuration.setMaxAge(Duration.ofHours(1));
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
以上2個(gè)方法,都可以實(shí)現(xiàn)在Spring Security環(huán)境下的跨域訪問。文章來源:http://www.zghlxwxcb.cn/news/detail-454877.html
2.3 方式三:支持OAuth2的跨域訪問
我們開發(fā)時(shí),還有一種情況就是支持 OAuth2 相關(guān)接口的跨域,比如用戶要訪問 OAuth2 中的 /oauth/token 等接口。我們可以配置一個(gè)全局的 CorsFilter 跨域過濾器類,核心代碼如下:文章來源地址http://www.zghlxwxcb.cn/news/detail-454877.html
/**
* 跨域配置方式3:定義全局跨域過濾器
**/
@Configuration
public class GlobalCorsConfiguration {
@Bean
public CorsFilter corsFilter() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowCredentials(true);
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(urlBasedCorsConfigurationSource);
}
}
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//跨域方式3:
http.requestMatchers()
.antMatchers(HttpMethod.OPTIONS, "/oauth/**")
.and()
.csrf()
.disable()
.formLogin()
.and()
.cors();
}
}
2.4 方式4 :自定義一個(gè)全局跨域處理Filter
public class CorsFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String orignalHeader = StringUtils.defaultIfBlank(request.getHeader("Origin"), "*");
// 指定本次預(yù)檢請求的有效期
response.setHeader("Access-Control-Max-Age", "3600");
// 服務(wù)器支持的所有頭信息字段
response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
response.setHeader("Access-Control-Allow-Origin", orignalHeader);
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
filterChain.doFilter(request, response);
}
}
public class WebMvcConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(new CorsFilter (), WebAsyncManagerIntegrationFilter.class);
}
}
到了這里,關(guān)于Spring Security系列教程之解決Spring Security環(huán)境中的跨域問題的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!