共用方式為


請求轉換

要求轉換包括要求路徑、查詢、HTTP 版本、方法和標頭。 在程式代碼中,這些是由 RequestTransformContext 物件表示,並由抽象類 RequestTransform 的實作處理。

注意事項:

  • Proxy 要求方案(HTTP/https)、權限和路徑基底,從目的伺服器位址(https://localhost:10001/Path/Base 在上述範例中)提取,並不應以轉換形式修改。
  • 主機標頭可以透過不依賴權威機制的轉換來覆寫,請參閱下面的RequestHeader
  • 建構 Proxy 要求時,不會使用要求的原始 PathBase 屬性,請參閱 X-Forwarded
  • 所有傳入的請求標頭預設會被複製到 Proxy 請求中,唯獨 Host 標頭除外(請參閱Defaults預設值)。 預設情況下也會添加 X-Forwarded 標頭。 您可以使用下列轉換來設定這些行為。 您可以指定其他要求標頭,或藉由將標頭設定為空值來排除要求標頭。

下列是內建的轉換,這些轉換是通過其主要配置鍵識別的。 這些轉換會依照路由組態中指定的順序套用。

路徑前綴

修改新增前置詞值的要求路徑

鑰匙 價值 為必填項目
路徑前綴 開頭為 『/』 的路徑 是的

設定:

{ "PathPrefix": "/prefix" }

程式碼:

routeConfig = routeConfig.WithTransformPathPrefix(prefix: "/prefix");
transformBuilderContext.AddPathPrefix(prefix: "/prefix");

範例:
/request/path 變成 /prefix/request/path

這會在要求路徑前面加上指定的值。

移除前綴路徑

修改移除前置詞值的要求路徑

鑰匙 價值 為必填項目
移除前綴路徑 開頭為 『/』 的路徑 是的

設定:

{ "PathRemovePrefix": "/prefix" }

程式碼:

routeConfig = routeConfig.WithTransformPathRemovePrefix(prefix: "/prefix");
transformBuilderContext.AddPathRemovePrefix(prefix: "/prefix");

範例:
/prefix/request/path 變成 /request/path
/prefix2/request/path 未修改

這會從要求路徑中移除相符的前置詞。 比對是在路徑區段界限上建立的。/ 如果前置詞不相符,則不會進行任何變更。

PathSet

以指定的值取代要求路徑

鑰匙 價值 為必填項目
PathSet 開頭為 『/』 的路徑 是的

設定:

{ "PathSet": "/newpath" }

程式碼:

routeConfig = routeConfig.WithTransformPathSet(path: "/newpath");
transformBuilderContext.AddPathSet(path: "/newpath");

範例:
/request/path 變成 /newpath

這會使用指定的值來設定要求路徑。

路徑模式

使用模式範本取代要求路徑

鑰匙 價值 為必填項目
路徑模式 開頭為 『/』 的路徑範本 是的

設定:

{ "PathPattern": "/my/{plugin}/api/{**remainder}" }

程式碼:

routeConfig = routeConfig.WithTransformPathRouteValues(pattern: new PathString("/my/{plugin}/api/{**remainder}"));
transformBuilderContext.AddPathRouteValues(pattern: new PathString("/my/{plugin}/api/{**remainder}"));

這會使用指定的值來設定要求路徑,並將任何 {} 區段取代為相關聯的路由值。 {} 拿掉沒有相符路由值的區段。 最後 {} 的區段可以標示為 {**remainder} ,表示這是可能包含多個路徑區段的 catch-all 區段。 如需路由範本的詳細資訊,請參閱 ASP.NET Core 的 路由檔

範例:

步驟 價值
路由定義 /api/{plugin}/stuff/{**remainder}
請求路徑 /api/v1/stuff/more/stuff
插件值 v1
餘數值 more/stuff
路徑模式 /my/{plugin}/api/{**remainder}
結果 /my/v1/api/more/stuff

查詢值參數

在要求查詢字串中新增或取代參數

鑰匙 價值 為必填項目
查詢值參數 查詢字串參數的名稱 是的
設定/追加 靜態值 是的

設定:

{
  "QueryValueParameter": "foo",
  "Append": "bar"
}

程式碼:

routeConfig = routeConfig.WithTransformQueryValue(queryKey: "foo", value: "bar", append: true);
transformBuilderContext.AddQueryValue(queryKey: "foo", value: "bar", append: true);

這會新增具有名稱 foo 的查詢字串參數,並將其設定為靜態值 bar

範例:

步驟 價值
查詢 ?a=b
查詢值參數 foo
添附 remainder
結果 ?a=b&foo=remainder

查詢路由參數

從路由組態中取得值,以新增或取代查詢字串參數

鑰匙 價值 為必填項目
查詢路由參數 查詢字串參數的名稱 是的
設定/追加 路由值的名稱 是的

設定:

{
  "QueryRouteParameter": "foo",
  "Append": "remainder"
}

程式碼:

routeConfig = routeConfig.WithTransformQueryRouteValue(queryKey: "foo", routeValueKey: "remainder", append: true);
transformBuilderContext.AddQueryRouteValue(queryKey: "foo", routeValueKey: "remainder", append: true);

這會新增具有名稱 foo 的查詢字串參數,並將其設定為相關聯路由值的值。

範例:

步驟 價值
路由定義 /api/{*remainder}
請求路徑 /api/more/stuff
餘數值 more/stuff
查詢路由參數 foo
添附 remainder
結果 ?foo=more/stuff

QueryRemoveParameter

從要求查詢字串中移除指定的參數

鑰匙 價值 為必填項目
QueryRemoveParameter 查詢字串參數的名稱 是的

設定:

{ "QueryRemoveParameter": "foo" }

程式碼:

routeConfig = routeConfig.WithTransformQueryRemoveKey(queryKey: "foo");
transformBuilderContext.AddQueryRemoveKey(queryKey: "foo");

如果請求中存在,這將移除名為 foo 的查詢字串參數。

範例:

步驟 價值
請求路徑 ?a=b&foo=c
QueryRemoveParameter foo
結果 ?a=b

HTTP 方法變更

變更要求中使用的 HTTP 方法

鑰匙 價值 為必填項目
HTTP 方法變更 要取代的 HTTP 方法 是的
設定 新的 HTTP 方法 是的

設定:

{
  "HttpMethodChange": "PUT",
  "Set": "POST"
}

程式碼:

routeConfig = routeConfig.WithTransformHttpMethodChange(fromHttpMethod: HttpMethods.Put, toHttpMethod: HttpMethods.Post);
transformBuilderContext.AddHttpMethodChange(fromHttpMethod: HttpMethods.Put, toHttpMethod: HttpMethods.Post);

這會將 PUT 要求變更為 POST。

請求標頭複製

設定傳入要求標頭是否複製到輸出要求

鑰匙 價值 預設 為必填項目
請求標頭複製 真/假 是的

設定:

{ "RequestHeadersCopy": "false" }

程式碼:

routeConfig = routeConfig.WithTransformCopyRequestHeaders(copy: false);
transformBuilderContext.CopyRequestHeaders = false;

這個設定決定是否所有進入的請求標頭都會複製到代理請求中。 默認狀態下會啟用此設定,您可以藉由將轉換配置為false值來停用該設定。 即使停用此功能,參考特定標頭的轉換仍會執行。

RequestHeader原始主機

指定是否應將傳入請求的 Host 標頭複製到代理請求

鑰匙 價值 預設 為必填項目
RequestHeader原始主機 真/假 假的 是的

設定:

{ "RequestHeaderOriginalHost": "true" }
routeConfig = routeConfig.WithTransformUseOriginalHostHeader(useOriginal: true);
transformBuilderContext.AddOriginalHost(true);

這會指定傳入要求主機標頭是否應該複製到代理要求。 此設定默認為停用狀態,但可通過配置轉換至 true 值來啟用。 直接參考 Host 標頭的轉換將會覆蓋此轉換。

請求標頭

新增或取代要求標頭

鑰匙 價值 為必填項目
請求標頭 標頭名稱 是的
設定/追加 標頭值 是的

設定:

{
  "RequestHeader": "MyHeader",
  "Set": "MyValue"
}

程式碼:

routeConfig = routeConfig.WithTransformRequestHeader(headerName: "MyHeader", value: "MyValue", append: false);
transformBuilderContext.AddRequestHeader(headerName: "MyHeader", value: "MyValue", append: false);

範例:

MyHeader: MyValue

這會設定或附加標頭名稱的數值。 Set 會取代任何現有的標頭。 Append 會新增具有指定值的額外標頭。 注意:不建議將 「設定為標頭值,而且可能會導致未定義的行為。

請求標頭路由值

從路由組態新增或取代標頭的值

鑰匙 價值 為必填項目
請求標頭 查詢字串參數的名稱 是的
設定/追加 路由值的名稱 是的

設定:

{
  "RequestHeaderRouteValue": "MyHeader",
  "Set": "MyRouteKey"
}

程式碼:

routeConfig = routeConfig.WithTransformRequestHeaderRouteValue(headerName: "MyHeader", routeValueKey: "key", append: false);
transformBuilderContext.AddRequestHeaderRouteValue(headerName: "MyHeader", routeValueKey: "key", append: false);

範例:

步驟 價值
路由定義 /api/{*remainder}
請求路徑 /api/more/stuff
餘數值 more/stuff
請求標頭從路由 foo
添附 remainder
結果 foo: more/stuff

這會設定或附加指定的標頭值,此值來自路由組態。 Set 會取代任何現有的標頭。 Append 會新增具有指定值的額外標頭。 注意:不建議將 「設定為標頭值,而且可能會導致未定義的行為。

移除請求標頭

拿掉要求標頭

鑰匙 價值 為必填項目
移除請求標頭 標頭名稱 是的

設定:

{
  "RequestHeaderRemove": "MyHeader"
}

程式碼:

routeConfig = routeConfig.WithTransformRequestHeaderRemove(headerName: "MyHeader");
transformBuilderContext.AddRequestHeaderRemove(headerName: "MyHeader");

範例:

MyHeader: MyValue
AnotherHeader: AnotherValue

這會移除已命名的標頭。

允許的請求頭部

鑰匙 價值 為必填項目
允許的請求頭部 允許的標頭名稱清單,以分號分隔。 是的

設定:

{
  "RequestHeadersAllowed": "Header1;header2"
}

程式碼:

routeConfig = routeConfig.WithTransformRequestHeadersAllowed("Header1", "header2");
transformBuilderContext.AddRequestHeadersAllowed("Header1", "header2");

YARP 預設會將大部分的要求標頭複製到 Proxy 要求(請參閱 RequestHeadersCopy)。 某些安全性模型只允許特定標頭被轉送。 此轉換會停用 RequestHeadersCopy,而且只會複製指定的標頭。 若未包含在允許清單中,修改或附加至現有標頭的其他轉換可能會受到影響。

請注意,有些標頭欄位 YARP 預設不會複製,因為它們是連線特定或與其他安全性相關的(例如,ConnectionAlt-Svc)。 將這些標頭名稱放在允許清單中將會略過該限制,但強烈建議您不要使用,因為它可能會對 Proxy 的功能造成負面影響,或造成安全性弱點。

範例:

Header1: value1
Header2: value2
AnotherHeader: AnotherValue

只有 header1 和 header2 會複製到 Proxy 要求。

X 轉寄

新增標頭,其中包含原始用戶端要求的相關信息

鑰匙 價值 預設 為必填項目
X 轉寄 預設動作(Set、Append、Remove、Off)套用至下列所有 X-Forwarded-* 設定 是的
為了 套用至此標頭的操作動作 * 請參閱 X-Forwarded
原型 套用至此標頭的操作動作 * 請參閱 X-Forwarded
主持人 套用至此標頭的操作動作 * 請參閱 X-Forwarded
前綴 套用至此標頭的操作動作 * 請參閱 X-Forwarded
標頭前綴 標頭名稱前綴 “X-Forwarded-”

動作 「Off」 會完全停用轉換。

設定:

{
  "X-Forwarded": "Set",
  "For": "Remove",
  "Proto": "Append",
  "Prefix": "Off",
  "HeaderPrefix": "X-Forwarded-"
}

程式碼:

routeConfig = routeConfig.WithTransformXForwarded(
  headerPrefix = "X-Forwarded-",
  ForwardedTransformActions xDefault = ForwardedTransformActions.Set,
  ForwardedTransformActions? xFor = null,
  ForwardedTransformActions? xHost = null,
  ForwardedTransformActions? xProto = null,
  ForwardedTransformActions? xPrefix = null);
transformBuilderContext.AddXForwarded(ForwardedTransformActions.Set);
transformBuilderContext.AddXForwardedFor(headerName: "X-Forwarded-For", ForwardedTransformActions.Append);
transformBuilderContext.AddXForwardedHost(headerName: "X-Forwarded-Host", ForwardedTransformActions.Append);
transformBuilderContext.AddXForwardedProto(headerName: "X-Forwarded-Proto", ForwardedTransformActions.Off);
transformBuilderContext.AddXForwardedPrefix(headerName: "X-Forwarded-Prefix", ForwardedTransformActions.Remove);

範例:

X-Forwarded-For: 5.5.5.5
X-Forwarded-Proto: https
X-Forwarded-Host: IncomingHost:5000
X-Forwarded-Prefix: /path/base

停用預設標頭:

{ "X-Forwarded": "Off" }
transformBuilderContext.UseDefaultForwarders = false;

當 Proxy 連線到目的地伺服器時,連線與用戶端對 Proxy 建立的連接無關。 目的地伺服器可能需要原始連線資訊來進行安全性檢查,並正確產生連結和重新導向的絕對 URI。 若要啟用將用戶端連線的相關信息傳遞至目的地,可以新增一組額外的標頭。 在Forwarded標準創立以前,常見的解決方案是使用X-Forwarded-*標頭。 沒有正式制定 X-Forwarded-* 標題的標準,實作可能會有所不同,請檢查目的地伺服器是否提供支援。

即使路由設定中未指定,預設仍會啟用此轉換。

X-Forwarded 值設定為用逗號分隔的清單,其中包含您需要啟用的標頭。 預設會啟用所有的標頭選項。 您可以藉由指定 值 "Off"來停用所有 。

「Prefix」指定用於每個標頭的標頭名稱前綴詞。 使用預設X-Forwarded-前置詞時,產生的標頭會是X-Forwarded-ForX-Forwarded-ProtoX-Forwarded-HostX-Forwarded-Prefix

轉換動作會指定如何將每個標頭與相同名稱的現有標頭結合。 它可以是「Set」、「Append」、「Remove」或「Off」(完全停用轉換)。 穿越多個代理伺服器的請求可能會累積這些標頭的清單,而目的伺服器將需要評估這些清單以確定原始值。 如果操作為「Set」,且請求中無法取得相關參數的值(例如 RemoteIpAddress 為 null),仍會移除任何已存在的標頭,以防止偽裝。

{Prefix}For 標頭值取自 HttpContext.Connection.RemoteIpAddress 代表前一個呼叫端的 IP 位址。 不包含埠口。 IPv6 位址不包含 [] 方括號。

{Prefix}Proto 標頭值取自 HttpContext.Request.Scheme 指出先前呼叫端是否使用 HTTP 或 HTTPS。

{Prefix}Host 標頭值取自傳入要求的主機標頭。 這與上述指定的 RequestHeaderOriginalHost 無關。 Unicode/IDN 主機名稱會以 Punycode 進行編碼。

{Prefix}Prefix 標頭值取自 HttpContext.Request.PathBase。 產生 Proxy 要求時不會使用 PathBase 屬性,因此目的地伺服器需要原始值才能正確產生連結和導向。 值採用百分比編碼 URI 格式。

轉發

新增標頭,其中包含原始用戶端要求的相關信息

鑰匙 價值 預設 為必填項目
轉發 逗號分隔清單,包含下列任何值:for、by、proto、host (無) 是的
ForFormat Random/RandomAndPort/RandomAndRandomPort/Unknown/UnknownAndPort/UnknownAndRandomPort/ip/IpAndRandomPort 隨機
ByFormat Random/RandomAndPort/RandomAndRandomPort/Unknown/UnknownAndPort/UnknownAndRandomPort/ip/IpAndRandomPort 隨機
行動 要套用至此標題的動作(Set、Append、Remove、Off) 設定

設定:

{
  "Forwarded": "by,for,host,proto",
  "ByFormat": "Random",
  "ForFormat": "IpAndPort",
  "Action": "Append"
},

程式碼:

routeConfig = routeConfig.WithTransformForwarded(useHost: true, useProto: true, forFormat: NodeFormat.IpAndPort, ByFormat: NodeFormat.Random, action: ForwardedTransformAction.Append);
transformBuilderContext.AddForwarded(useHost: true, useProto: true, forFormat: NodeFormat.IpAndPort, ByFormat: NodeFormat.Random, action: ForwardedTransformAction.Append);

範例:

Forwarded: proto=https;host="localhost:5001";for="[::1]:20173";by=_YQuN68tm6

標頭 Forwarded 是由 RFC 7239 所定義。 它整合了許多與非官方 X-Forwarded 標頭相同的功能,將資訊流向目的地伺服器,否則這些資訊在使用代理時會被遮蔽。

啟用此轉換將會停用預設 X 轉送轉換,因為它們會以另一種格式傳遞類似的資訊。 X 轉送轉換仍然可以明確啟用。

動作:這會指定轉換應該如何處理現有的轉送標頭。 它可以是「Set」、「Append」、「Remove」或「Off」(完全停用轉換)。 穿越多個代理伺服器的請求可能會累積這些標頭的清單,而目的伺服器將需要評估這些清單以確定原始值。

Proto:此值取自 HttpContext.Request.Scheme 指出先前呼叫端是否使用 HTTP 或 HTTPS。

主機:此值取自傳入要求的主機標頭。 這與上述指定的 RequestHeaderOriginalHost 無關。 Unicode/IDN 主機名稱會以 Punycode 進行編碼。

關於:這個值會識別之前的呼叫者。 IP 位址取自 HttpContext.Connection.RemoteIpAddress。 如需詳細資訊,請參閱下方的 ByFormat 和 ForFormat。

來源:這個值會識別代理伺服器接收請求的位置。 IP 位址取自 HttpContext.Connection.LocalIpAddress。 如需詳細資訊,請參閱下方的 ByFormat 和 ForFormat。

ByFormat 和 ForFormat:

RFC 允許 By 欄位和 For 欄位使用格式多樣。 它要求預設格式使用在此識別為 Random 的混淆識別碼。

格式 說明 範例
隨機 每次請求隨機生成的混淆識別碼。 這允許進行診斷追蹤情境,同時出於隱私考量限制唯一識別資訊的流通。 by=_YQuN68tm6
RandomAndPort 隨機識別碼加上端口。 by="_YQuN68tm6:80"
RandomAndRandomPort 隨機標識元加上埠的另一個隨機標識碼。 by="_YQuN68tm6:_jDw5Cf3tQ"
未知 這可以在上述實體的身分識別未知時使用,但 Proxy 伺服器仍想要發出要求轉送的訊號。 by=unknown
UnknownAndPort 未知識別符加上端口(如果可用)。 by="unknown:80"
未知和隨機端口 未知識別碼加上埠的隨機標識碼。 by="unknown:_jDw5Cf3tQ"
IP IPv4 位址或 IPv6 位址,包括括弧。 by="[::1]"
IpAndPort IP 位址加上埠。 by="[::1]:80"
IpAndRandomPort 埠的IP位址加上隨機識別碼。 by="[::1]:_jDw5Cf3tQ"

ClientCert

將入站連線上使用的客戶端憑證作為標頭轉送至目的地

鑰匙 價值 為必填項目
ClientCert 標頭名稱 是的

設定:

{ "ClientCert": "X-Client-Cert" }

程式碼:

routeConfig = routeConfig.WithTransformClientCertHeader(headerName: "X-Client-Cert");
transformBuilderContext.AddClientCertHeader(headerName: "X-Client-Cert");

範例:

X-Client-Cert: SSdtIGEgY2VydGlmaWNhdGU...

由於輸入和輸出連線是獨立的,因此必須有一種方法,才能將任何輸入用戶端憑證傳遞至目的地伺服器。 這項轉換會將從HttpContext.Connection.ClientCertificate提取的用戶端憑證進行Base64編碼,並設定為指定標頭名稱的值。 目的地伺服器可能需要該憑證來驗證用戶端。 沒有定義此標頭的標準,因此實作可能有所不同,請檢查目的伺服器是否支援。

根據預設,伺服器會對傳入客戶端憑證執行最少的驗證。 憑證應該在 Proxy 或目的地中驗證,如需詳細資訊,請參閱 用戶端憑證驗證 檔。

只有在連線上已經有客戶端憑證時,才會套用此轉換。 請參閱 選擇性憑證文件,以便在需要時依每個路由向用戶端要求憑證。