1. 程式人生 > >zuul+security跨域Cors問題解決

zuul+security跨域Cors問題解決

zuul+security跨域Cors問題解決

簡介

場景

在服務後臺都會出現跨域cors問題,不過一般spring解決起來比較方便,在框架+框架的基礎上,問題就顯得特別明顯了,各種衝突,不瞭解原始碼的執行原理,解決起來也是有心無力。

這裡介紹的是zuul配置了跨域,在前端呼叫仍然會出現跨域的問題。

一般沒有許可權的介面加上cors配置就會通過跨域的問題。不過在服務間呼叫具有許可權的功能,莫名的報跨域問題。

post特殊請求

在解決問題時發現 post 請求也有點特殊,這裡也需要處理一下。

post請求分為簡單請求和複雜請求。

CORS 中,可以使用 OPTIONS 方法發起一個預檢請求,以檢測實際請求是否可以被伺服器所接受。預檢請求報文中的 Access-Control-Request-Method

首部欄位告知伺服器實際請求所使用的 HTTP 方法;Access-Control-Request-Headers 首部欄位告知伺服器實際請求所攜帶的自定義首部欄位。伺服器基於從預檢請求獲得的資訊來判斷,是否接受接下來的實際請求。

以及 OPTIONS 未攜帶任何許可權相關的內容,會被認證攔截,我們也得放開 OPTIONS 型別請求

功能使用

Cross 解決

之前設定很簡單,習慣操作把之前的程式碼複製了過來,第一次操作是建立了一個 CorsFilter bean,但是簡單的請求確實通過了,不過許可權介面過不了,於是按照一些資料配置了下面的程式碼 注入了 FilterRegistrationBean

bean 還設定了 order 載入順序。

解決後無果 仍然和之前的效果一致。

/**
 * 跨域配置 C - Cross  O - Origin  R - Resource  S - Sharing
 *
 * @author purgeyao
 * @since 1.0
 */
@Configuration
//@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsConfig {

  @Bean
  public FilterRegistrationBean filterRegistrationBean() {
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    final CorsConfiguration config = new CorsConfiguration();

    config.setAllowCredentials(true);
    config.setAllowedOrigins(Arrays.asList("*"));
    config.setAllowedHeaders(Arrays.asList("*"));
    config.setAllowedMethods(Arrays.asList("*"));
    config.setMaxAge(300L);

    source.registerCorsConfiguration("/**", config);
    CorsFilter corsFilter = new CorsFilter(source);
    FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(corsFilter);
    filterRegistrationBean.setOrder(0);
    return filterRegistrationBean;
  }
}

在一些資料+原始碼的幫助下,嘗試了下面程式碼:

這次實現了 CorsFilter 類 載入了 @Order 順序為 (Ordered.HIGHEST_PRECEDENCE) 最優先。

/**
 * 解決 zuul+oauth2 跨域配置 C - Cross  O - Origin  R - Resource  S - Sharing
 *
 * @author purgeyao
 * @since 1.0
 */
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class AjaxCorsFilter extends CorsFilter {

  public AjaxCorsFilter() {
    super(configurationSource());
  }

  private static UrlBasedCorsConfigurationSource configurationSource() {
    CorsConfiguration corsConfig = new CorsConfiguration();
//        List<String> allowedHeaders = Arrays.asList("x-auth-token", "content-type", "X-Requested-With", "XMLHttpRequest");
    List<String> exposedHeaders = Arrays
        .asList("x-auth-token", "content-type", "X-Requested-With", "XMLHttpRequest");
//        List<String> allowedMethods = Arrays.asList("POST", "GET", "DELETE", "PUT", "OPTIONS");

    List<String> allowedHeaders = Arrays.asList("*");
    List<String> allowedMethods = Arrays.asList("*");
    List<String> allowedOrigins = Arrays.asList("*");
    corsConfig.setAllowedHeaders(allowedHeaders);
    corsConfig.setAllowedMethods(allowedMethods);
    corsConfig.setAllowedOrigins(allowedOrigins);
    corsConfig.setExposedHeaders(exposedHeaders);
    corsConfig.setMaxAge(36000L);
    corsConfig.setAllowCredentials(true);

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", corsConfig);
    return source;
  }
}

哈哈哈,解決了,但是有沒有感覺到莫名其妙啊,經過了解

發現其實只是一個載入順序的問題,我們上面注入的 FilterRegistrationBean 也可以使用的,只是在設定order的時候有點問題 需要設定比 security 優先順序高,改為 Ordered.HIGHEST_PRECEDENCE 發現成功可以通過跨域了。

/**
 * 跨域配置 C - Cross  O - Origin  R - Resource  S - Sharing
 *
 * @author purgeyao
 * @since 1.0
 */
@Configuration
//@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsConfig {

  @Bean
  public FilterRegistrationBean filterRegistrationBean() {
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    final CorsConfiguration config = new CorsConfiguration();

    config.setAllowCredentials(true);
    config.setAllowedOrigins(Arrays.asList("*"));
    config.setAllowedHeaders(Arrays.asList("*"));
    config.setAllowedMethods(Arrays.asList("*"));
    config.setMaxAge(300L);

    source.registerCorsConfiguration("/**", config);
    CorsFilter corsFilter = new CorsFilter(source);
    FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(corsFilter);
    // 設定為 Ordered.HIGHEST_PRECEDENCE
    filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return filterRegistrationBean;
  }
}

解決解決。。。

OPTIONS請求解決

有關 OPTIONS(NDN
web docs) 介紹。

在傳送 post 請求 會發現在真正傳送之前會有一個 OPTIONS 請求。

OPTIONS 為攜帶任何有狀態的認證資訊,被許可權攔截下來異常,就沒有之後的真正請求了。

我們只需要吧 OPTIONS 請求放開 返回200狀態即可。

有很多辦法做到,可以在zuul閘道器放過,也可以通過 security 新增 忽略攔截列表。

public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    ...
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        ...
        // 新增忽略攔截OPTIONS 型別的請求
        http.authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll();
        ...
    }
}

萬事大吉。

總結

簡單的bug解決起來簡單點,不過遇到交集的bug,有心無力的感覺,莫名其妙的問題,需要耐心觀察原始碼執行原理。

示例程式碼地址:zuul-security

作者GitHub:
Purgeyao 歡迎關注

qq交流群: 812321371 微信交流群: MercyYao

微信公眾號:

相關推薦

zuul+securityCors問題解決

zuul+security跨域Cors問題解決 簡介 場景 在服務後臺都會出現跨域cors問題,不過一般spring解決起來比較方便,在框架+框架的基礎上,問題就顯得特別明顯了,各種衝突,不瞭解原始碼的執行原理,解決起來也是有心無力。 這裡介紹的是zuul配置了跨域,在前端呼叫仍然會出現跨域的問題。 一般沒有

C#進階系列——WebApi 問題解決方案:CORS

dea ati ice pro target default 異常 測試工具 復雜 前言:上篇總結了下WebApi的接口測試工具的使用,這篇接著來看看WebAPI的另一個常見問題:跨域問題。本篇主要從實例的角度分享下CORS解決跨域問題一些細節。 WebApi系列文章

前端-關於CORS解決方案,面向服務端

red 瀏覽器 環境 和我 methods retrieve name 後臺 一件事 最近自己在寫後臺管理系統的時候,並沒有采用jsp、freemaker、葉子等模板技術,而是由後端提供數據api,前端通過AJAX和JQuery來動態操作頁面上的一些div、table元素,

WebAPI Ajax 請求解決方法(CORS實現)

custom XML header 就會 情況 取數 -o cross serve 概述 ASP.NET Web API 的好用使用過的都知道,沒有復雜的配置文件,一個簡單的ApiController加上需要的Action就能工作。 但是在使用API的時候總會遇到跨

CORS 與 TP5中解決方案

在做專案過程中,使用Vue-element-admin作為前端,ThinkPHP5作為後端框架進行開發,會遭遇跨域問題,本文給出ThinkPHP5解決跨域 1.CORS的概念     CORS(Cross-Origin Resource Sharing 跨源資源共享),當

Angular2,Springboot,Zuul,ShiroCORS請求踩坑實錄

前言:前後端分離,業務分離,閘道器路由等已經成為當下web application開發的流行趨勢。前端以單頁面路由為核心的框架為主體,可以單獨部署在nodejs或nginx上。後端以springboot為代表的分散式微服務框架為主體,可以獨立執行在任何埠上。相互通過符合restful規範的介面訪問或資料交換。

Django學習【第26篇】:後端CORS解決問題 解決問題

解決跨域問題 一、為什麼會有跨域問題? 是因為瀏覽器的同源策略是對ajax請求進行阻攔了,但是不是所有的請求都給做跨域,像是一般的href屬性,a標籤什麼的都不攔截。

WebApi 問題解決方案:CORS

前兩篇文章介紹了WebApi專案的建立和測試,今天來說說WebApi跨域訪問的問題。本篇主要介紹了利用CORS解決跨域問題一些細節和具體步驟,下面來看看吧。 一、釋出WebApi 既然是解決WebApi跨域問題,那WebApi(http://localhost:9002)

前後端互動問題解決方案,資源共享(CORS

跨域資源共享(CORS) 普通跨域請求:只服務端設定Access-Control-Allow-Origin即可,前端無須設定,若要帶cookie請求:前後端都需要設定。 需注意的是:由於同源策略的限制,所讀取的cookie為跨域請求介面所在域的cookie,而非當前頁。如

前端CORS請求介面問題解決方案 (古月)

先配置Nginx 先舉例 以下是我們常用的nginx站點配置(PHP網站為例) server { listen 監聽埠; server_name 域名部分; set $root_path 目錄部分; root $root_path; i

Spring Boot Security訪問 cors

使用Spring Security 在Boot 專案中,實現前後端分離的跨域訪問,只需要簡單的配置即可。 未使用Security 的Boot 專案 在未使用Spring Security 的Boot 專案中,只需要在 Application.java 中新增如

問題解決方式(HttpClient安全 &amp; jsonp)

str 輕量 mov fontsize 使用 col utf8 des conn 1 錯誤場景 今天要把項目部署到外網的時候,出現了這種問題, 我把兩個項目放到自己本機的

前端解決方式

指定 模式 輸出 enc oauth t對象 TTT 註意 pos 前端與服務端數據交互時,涉及到跨域的一些問題。JavaScript出於安全的考慮,禁止了跨域調用其他頁面的對象,也即同源策略限制了一個源(origin)中加載文本或腳本與來自其它源(origin)中資源的交

IE9版本號下面ajax 問題解決

jquer mic 資料 沒有 ie11 自己 sport 百度 nor ajax跨域請求數據在谷歌火狐我本地IE11都是沒問題的。 讓測試就發現問題了,IE8下請求不到數據。然後我查看一下自己寫的js看有沒有不兼容問題。但是都沒有啊。為什麽就請求不到呢。 我把

CORS

cors一、跨域CORS是什麽當一個資源從與該資源本身所在的服務器的域或端口不同的域或不同的端口請求一個資源時,瀏覽器會發起一個跨域 HTTP 請求。出於安全考慮,瀏覽器會限制從腳本內發起的跨域HTTP請求或者攔截了服務器返回內容。例如,XMLHttpRequest 和 Fetch 遵循同源策略。因此,使用

ajax終極解決辦法!

data val 跨域請求 clas 自己 信息 跨域問題 cal header 在使用 ajax 的時候,往往需要通過 ajax 跨域請求一些? 但是 XMLHTTPRequest 是不支持跨域的,所以產生了 JSONP 這個東西來解決跨域,當然解決跨域的方式有很多種..

轉 Js CORS報錯 Response for preflight has invalid HTTP status code 405

control logs web col 奇怪 flight protected protoc tex 轉自:http://www.cnblogs.com/SilenceTom/p/6697484.html 調用接口遇到Response for preflight

cors中如何傳遞cookie(前端為什麽無法向後端傳遞cookie?)

con sam bsp ble 情況 需求 nbsp 什麽 gin 沒有跨域 後端server只要在回應頭部‘set-cookie’,那麽就會有cookie產生並保存在客戶端client。 等到client再次向後端server發送請求時瀏覽器的機制就會自動攜帶cook

ajax請求解決方案

tro cti jquer 解決方案 tab all ajax跨域 自帶 b-s 大家好,今天我們學習了js的跨域請求的解決方案,由於JS中存在同源策略,當請求不同協議名,不同端口號、不同主機名下面的文件時,將會違背同源策略,無法請求成功!需要進行跨域處理! 方案一、後臺P

ajax 請求解決方案

allow option ajax cred eth post delet 求解 delete response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access