From 4fe955c31533d8fee82fbec7eedaca61fc3fd4d2 Mon Sep 17 00:00:00 2001 From: Dominick Baier Date: Sat, 25 Sep 2021 12:36:37 +0200 Subject: [PATCH 1/2] first cut --- src/Duende.Bff/BffOptions.cs | 5 --- .../Proxy/DefaultHttpTransformerFactory.cs | 22 +++++------ test/Duende.Bff.Tests/Headers/General.cs | 37 +------------------ 3 files changed, 12 insertions(+), 52 deletions(-) diff --git a/src/Duende.Bff/BffOptions.cs b/src/Duende.Bff/BffOptions.cs index c0ca1e5b7..560df8777 100644 --- a/src/Duende.Bff/BffOptions.cs +++ b/src/Duende.Bff/BffOptions.cs @@ -63,11 +63,6 @@ public class BffOptions /// public bool ForwardIncomingXForwardedHeaders { get; set; } = false; - /// - /// Specifies additional headers to forward to remote API endpoints. - /// - public ISet ForwardedHeaders { get; set; } = new HashSet(); - /// /// Specifies how the path for remote API endpoints gets transformed. /// Defaults to removing the configured local prefix. diff --git a/src/Duende.Bff/Proxy/DefaultHttpTransformerFactory.cs b/src/Duende.Bff/Proxy/DefaultHttpTransformerFactory.cs index 8b67750d8..9214fae66 100644 --- a/src/Duende.Bff/Proxy/DefaultHttpTransformerFactory.cs +++ b/src/Duende.Bff/Proxy/DefaultHttpTransformerFactory.cs @@ -40,20 +40,18 @@ public virtual HttpTransformer CreateTransformer(string localPath, string access { return TransformBuilder.Create(context => { - context.CopyRequestHeaders = false; - - // todo: should x-forwarded be added by default? + // apply default YARP logic for forwarding headers + context.CopyRequestHeaders = true; + + // use our config options to apply x-forwarded-* context.UseDefaultForwarders = false; - + + // always remove cookie header since this contains the session + context.RequestTransforms.Add(new RequestHeaderRemoveTransform("Cookie")); + + // transform path context.RequestTransforms.Add(new PathStringTransform(Options.PathTransformMode, localPath)); - context.RequestTransforms.Add(new ForwardHeadersRequestTransform(new[] - { HeaderNames.Accept, HeaderNames.ContentLength, HeaderNames.ContentType })); - - if (Options.ForwardedHeaders.Any()) - { - context.RequestTransforms.Add(new ForwardHeadersRequestTransform(Options.ForwardedHeaders)); - } - + if (Options.AddXForwardedHeaders) { var action = ForwardedTransformActions.Set; diff --git a/test/Duende.Bff.Tests/Headers/General.cs b/test/Duende.Bff.Tests/Headers/General.cs index 3c49a2b1e..0e5b904b0 100644 --- a/test/Duende.Bff.Tests/Headers/General.cs +++ b/test/Duende.Bff.Tests/Headers/General.cs @@ -28,32 +28,9 @@ public async Task local_endpoint_should_receive_standard_headers() } [Fact] - public async Task custom_header_should_not_be_forwarded_by_default() + public async Task custom_header_should_be_forwarded() { BffHost.BffOptions.AddXForwardedHeaders = false; - - await BffHost.InitializeAsync(); - - var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_anon_only/test")); - req.Headers.Add("x-csrf", "1"); - req.Headers.Add("x-custom", "custom"); - var response = await BffHost.BrowserClient.SendAsync(req); - - response.IsSuccessStatusCode.Should().BeTrue(); - var json = await response.Content.ReadAsStringAsync(); - var apiResult = JsonSerializer.Deserialize(json); - - apiResult.RequestHeaders.Count.Should().Be(1); - - apiResult.RequestHeaders["Host"].Single().Should().Be("api"); - } - - [Fact] - public async Task custom_header_should_be_forwarded_when_configured() - { - BffHost.BffOptions.AddXForwardedHeaders = false; - BffHost.BffOptions.ForwardedHeaders.Add("x-custom"); - await BffHost.InitializeAsync(); var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_anon_only/test")); @@ -65,8 +42,6 @@ public async Task custom_header_should_be_forwarded_when_configured() var json = await response.Content.ReadAsStringAsync(); var apiResult = JsonSerializer.Deserialize(json); - apiResult.RequestHeaders.Count.Should().Be(2); - apiResult.RequestHeaders["Host"].Single().Should().Be("api"); apiResult.RequestHeaders["x-custom"].Single().Should().Be("custom"); } @@ -75,8 +50,6 @@ public async Task custom_header_should_be_forwarded_when_configured() public async Task custom_header_should_be_forwarded_and_xforwarded_headers_should_be_created() { BffHost.BffOptions.AddXForwardedHeaders = true; - BffHost.BffOptions.ForwardedHeaders.Add("x-custom"); - await BffHost.InitializeAsync(); var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_anon_only/test")); @@ -87,9 +60,7 @@ public async Task custom_header_should_be_forwarded_and_xforwarded_headers_shoul response.IsSuccessStatusCode.Should().BeTrue(); var json = await response.Content.ReadAsStringAsync(); var apiResult = JsonSerializer.Deserialize(json); - - apiResult.RequestHeaders.Count.Should().Be(4); - + apiResult.RequestHeaders["X-Forwarded-Host"].Single().Should().Be("app"); apiResult.RequestHeaders["X-Forwarded-Proto"].Single().Should().Be("https"); apiResult.RequestHeaders["Host"].Single().Should().Be("api"); @@ -101,8 +72,6 @@ public async Task custom_and_xforwarded_header_should_be_forwarded_and_xforwarde { BffHost.BffOptions.AddXForwardedHeaders = true; BffHost.BffOptions.ForwardIncomingXForwardedHeaders = true; - BffHost.BffOptions.ForwardedHeaders.Add("x-custom"); - await BffHost.InitializeAsync(); var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_anon_only/test")); @@ -115,8 +84,6 @@ public async Task custom_and_xforwarded_header_should_be_forwarded_and_xforwarde var json = await response.Content.ReadAsStringAsync(); var apiResult = JsonSerializer.Deserialize(json); - apiResult.RequestHeaders.Count.Should().Be(4); - apiResult.RequestHeaders["X-Forwarded-Proto"].Single().Should().Be("https"); apiResult.RequestHeaders["Host"].Single().Should().Be("api"); apiResult.RequestHeaders["x-custom"].Single().Should().Be("custom"); From 1d981e4b0de3ecdfe2cf28d77d1aaee838d31375 Mon Sep 17 00:00:00 2001 From: Dominick Baier Date: Sat, 25 Sep 2021 12:40:57 +0200 Subject: [PATCH 2/2] remove old transform --- .../Proxy/ForwardHeadersRequestTransform.cs | 54 ------------------- 1 file changed, 54 deletions(-) delete mode 100644 src/Duende.Bff/Proxy/ForwardHeadersRequestTransform.cs diff --git a/src/Duende.Bff/Proxy/ForwardHeadersRequestTransform.cs b/src/Duende.Bff/Proxy/ForwardHeadersRequestTransform.cs deleted file mode 100644 index cd7f46d08..000000000 --- a/src/Duende.Bff/Proxy/ForwardHeadersRequestTransform.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) Duende Software. All rights reserved. -// See LICENSE in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Extensions.Primitives; -using Yarp.ReverseProxy.Transforms; - -namespace Duende.Bff -{ - /// - /// Forwards headers - /// - public class ForwardHeadersRequestTransform : RequestTransform - { - private readonly IEnumerable _headerNames; - - /// - /// ctor - /// - /// - public ForwardHeadersRequestTransform(IEnumerable headerNames) - { - _headerNames = headerNames; - } - - /// - public override ValueTask ApplyAsync(RequestTransformContext context) - { - foreach (var (headerName, headerValue) in context.HttpContext.Request.Headers) - { - if (StringValues.IsNullOrEmpty(headerValue)) - { - continue; - } - - // Filter out HTTP/2 pseudo headers like ":method" and ":path", those go into other fields. - if (headerName.Length > 0 && headerName[0] == ':') - { - continue; - } - - if (_headerNames.Contains(headerName, StringComparer.OrdinalIgnoreCase)) - { - AddHeader(context, headerName, headerValue); - } - } - - return default; - } - } -} \ No newline at end of file