Skip to content

Commit

Permalink
#309 allow users to ignore ssl warnings, not sure this is advisable (#…
Browse files Browse the repository at this point in the history
…325)

* #309 allow users to ignore ssl warnings, not sure this is advisable

* #309 docs for ssl ignore
  • Loading branch information
TomPallister authored Apr 22, 2018
1 parent 4f061f2 commit 636d116
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 12 deletions.
14 changes: 13 additions & 1 deletion docs/features/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ Here is an example ReRoute configuration, You don't need to set all of these thi
"UseCookieContainer": true,
"UseTracing": true
},
"UseServiceDiscovery": false
"UseServiceDiscovery": false,
"DangerousAcceptAnyServerCertificateValidator": false
}
More information on how to use these options is below..
Expand Down Expand Up @@ -160,3 +161,14 @@ noticed that the cookies were being shared. I tried to think of a nice way to ha
that means each request gets a new client and therefore a new cookie container. If you clear the cookies from the cached client container you get race conditions due to inflight
requests. This would also mean that subsequent requests dont use the cookies from the previous response! All in all not a great situation. I would avoid setting
UseCookieContainer to true unless you have a really really good reason. Just look at your response headers and forward the cookies back with your next request!

SSL Errors
----------

Id you want to ignore SSL warnings / errors set the following in your ReRoute config.

.. code-block:: json
"DangerousAcceptAnyServerCertificateValidator": false
I don't reccomend doing this, I suggest creating your own certificate and then getting it trusted by your local / remote machine if you can.
10 changes: 9 additions & 1 deletion src/Ocelot/Configuration/Builder/DownstreamReRouteBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public class DownstreamReRouteBuilder
private List<string> _delegatingHandlers;
private List<AddHeader> _addHeadersToDownstream;
private List<AddHeader> _addHeadersToUpstream;
private bool _dangerousAcceptAnyServerCertificateValidator;

public DownstreamReRouteBuilder()
{
Expand Down Expand Up @@ -241,6 +242,12 @@ public DownstreamReRouteBuilder WithAddHeadersToUpstream(List<AddHeader> addHead
return this;
}

public DownstreamReRouteBuilder WithDangerousAcceptAnyServerCertificateValidator(bool dangerousAcceptAnyServerCertificateValidator)
{
_dangerousAcceptAnyServerCertificateValidator = dangerousAcceptAnyServerCertificateValidator;
return this;
}

public DownstreamReRoute Build()
{
return new DownstreamReRoute(
Expand Down Expand Up @@ -272,7 +279,8 @@ public DownstreamReRoute Build()
_reRouteKey,
_delegatingHandlers,
_addHeadersToDownstream,
_addHeadersToUpstream);
_addHeadersToUpstream,
_dangerousAcceptAnyServerCertificateValidator);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ private DownstreamReRoute SetUpDownstreamReRoute(FileReRoute fileReRoute, FileGl
.WithDelegatingHandlers(fileReRoute.DelegatingHandlers)
.WithAddHeadersToDownstream(hAndRs.AddHeadersToDownstream)
.WithAddHeadersToUpstream(hAndRs.AddHeadersToUpstream)
.WithDangerousAcceptAnyServerCertificateValidator(fileReRoute.DangerousAcceptAnyServerCertificateValidator)
.Build();

return reRoute;
Expand Down
5 changes: 4 additions & 1 deletion src/Ocelot/Configuration/DownstreamReRoute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ public DownstreamReRoute(
string reRouteKey,
List<string> delegatingHandlers,
List<AddHeader> addHeadersToDownstream,
List<AddHeader> addHeadersToUpstream)
List<AddHeader> addHeadersToUpstream,
bool dangerousAcceptAnyServerCertificateValidator)
{
DangerousAcceptAnyServerCertificateValidator = dangerousAcceptAnyServerCertificateValidator;
AddHeadersToDownstream = addHeadersToDownstream;
DelegatingHandlers = delegatingHandlers;
Key = key;
Expand Down Expand Up @@ -97,5 +99,6 @@ public DownstreamReRoute(
public List<string> DelegatingHandlers {get;private set;}
public List<AddHeader> AddHeadersToDownstream {get;private set;}
public List<AddHeader> AddHeadersToUpstream { get; private set; }
public bool DangerousAcceptAnyServerCertificateValidator { get; private set; }
}
}
1 change: 1 addition & 0 deletions src/Ocelot/Configuration/File/FileReRoute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,6 @@ public FileReRoute()
public List<string> DelegatingHandlers {get;set;}
public int Priority { get;set; }
public int Timeout { get; set; }
public bool DangerousAcceptAnyServerCertificateValidator { get; set; }
}
}
25 changes: 16 additions & 9 deletions src/Ocelot/Requester/HttpClientBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public class HttpClientBuilder : IHttpClientBuilder
private string _cacheKey;
private HttpClient _httpClient;
private IHttpClient _client;
private HttpClientHandler _httpclientHandler;
private readonly TimeSpan _defaultTimeout;

public HttpClientBuilder(
Expand All @@ -33,9 +32,9 @@ public HttpClientBuilder(
_defaultTimeout = TimeSpan.FromSeconds(90);
}

public IHttpClient Create(DownstreamContext request)
public IHttpClient Create(DownstreamContext context)
{
_cacheKey = GetCacheKey(request);
_cacheKey = GetCacheKey(context);

var httpClient = _cacheHandlers.Get(_cacheKey);

Expand All @@ -44,18 +43,26 @@ public IHttpClient Create(DownstreamContext request)
return httpClient;
}

_httpclientHandler = new HttpClientHandler
var httpclientHandler = new HttpClientHandler
{
AllowAutoRedirect = request.DownstreamReRoute.HttpHandlerOptions.AllowAutoRedirect,
UseCookies = request.DownstreamReRoute.HttpHandlerOptions.UseCookieContainer,
AllowAutoRedirect = context.DownstreamReRoute.HttpHandlerOptions.AllowAutoRedirect,
UseCookies = context.DownstreamReRoute.HttpHandlerOptions.UseCookieContainer,
CookieContainer = new CookieContainer()
};

var timeout = request.DownstreamReRoute.QosOptionsOptions.TimeoutValue == 0
if(context.DownstreamReRoute.DangerousAcceptAnyServerCertificateValidator)
{
httpclientHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;

_logger
.LogWarning($"You have ignored all SSL warnings by using DangerousAcceptAnyServerCertificateValidator for this DownstreamReRoute, UpstreamPathTemplate: {context.DownstreamReRoute.UpstreamPathTemplate}, DownstreamPathTemplate: {context.DownstreamReRoute.DownstreamPathTemplate}");
}

var timeout = context.DownstreamReRoute.QosOptionsOptions.TimeoutValue == 0
? _defaultTimeout
: TimeSpan.FromMilliseconds(request.DownstreamReRoute.QosOptionsOptions.TimeoutValue);
: TimeSpan.FromMilliseconds(context.DownstreamReRoute.QosOptionsOptions.TimeoutValue);

_httpClient = new HttpClient(CreateHttpMessageHandler(_httpclientHandler, request.DownstreamReRoute))
_httpClient = new HttpClient(CreateHttpMessageHandler(httpclientHandler, context.DownstreamReRoute))
{
Timeout = timeout
};
Expand Down
3 changes: 3 additions & 0 deletions test/Ocelot.AcceptanceTests/Ocelot.AcceptanceTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="idsrv3test.pfx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
Expand Down
146 changes: 146 additions & 0 deletions test/Ocelot.AcceptanceTests/SslTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration.File;
using Shouldly;
using TestStack.BDDfy;
using Xunit;

namespace Ocelot.AcceptanceTests
{
public class SslTests : IDisposable
{
private IWebHost _builder;
private readonly Steps _steps;
private string _downstreamPath;

public SslTests()
{
_steps = new Steps();
}

[Fact]
public void should_dangerous_accept_any_server_certificate_validator()
{
int port = 51129;

var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "https",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = port,
}
},
UpstreamPathTemplate = "/",
UpstreamHttpMethod = new List<string> { "Get" },
DangerousAcceptAnyServerCertificateValidator = true
}
}
};

this.Given(x => x.GivenThereIsAServiceRunningOn($"https://localhost:{port}", "/", 200, "Hello from Laura", port))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
.BDDfy();
}

[Fact]
public void should_not_dangerous_accept_any_server_certificate_validator()
{
int port = 52129;

var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "https",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = port,
}
},
UpstreamPathTemplate = "/",
UpstreamHttpMethod = new List<string> { "Get" },
DangerousAcceptAnyServerCertificateValidator = false
}
}
};

this.Given(x => x.GivenThereIsAServiceRunningOn($"https://localhost:{port}", "/", 200, "Hello from Laura", port))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.NotFound))
.BDDfy();
}

private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody, int port)
{
_builder = new WebHostBuilder()
.UseUrls(baseUrl)
.UseKestrel(options =>
{
options.Listen(IPAddress.Loopback, port, listenOptions =>
{
listenOptions.UseHttps("idsrv3test.pfx", "idsrv3test");
});
})
.UseContentRoot(Directory.GetCurrentDirectory())
.Configure(app =>
{
app.UsePathBase(basePath);
app.Run(async context =>
{
_downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
if(_downstreamPath != basePath)
{
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync("downstream path didnt match base path");
}
else
{
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync(responseBody);
}
});
})
.Build();

_builder.Start();
}

internal void ThenTheDownstreamUrlPathShouldBe(string expectedDownstreamPath)
{
_downstreamPath.ShouldBe(expectedDownstreamPath);
}

public void Dispose()
{
_builder?.Dispose();
_steps.Dispose();
}
}
}
24 changes: 24 additions & 0 deletions test/Ocelot.UnitTests/Requester/HttpClientBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,25 @@ public void should_build_http_client()
.BDDfy();
}

[Fact]
public void should_log_if_ignoring_ssl_errors()
{
var reRoute = new DownstreamReRouteBuilder()
.WithIsQos(false)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false))
.WithReRouteKey("")
.WithQosOptions(new QoSOptionsBuilder().Build())
.WithDangerousAcceptAnyServerCertificateValidator(true)
.Build();

this.Given(x => GivenTheFactoryReturns())
.And(x => GivenARequest(reRoute))
.When(x => WhenIBuild())
.Then(x => ThenTheHttpClientShouldNotBeNull())
.Then(x => ThenTheDangerousAcceptAnyServerCertificateValidatorWarningIsLogged())
.BDDfy();
}

[Fact]
public void should_call_delegating_handlers_in_order()
{
Expand Down Expand Up @@ -111,6 +130,11 @@ public void should_re_use_cookies_from_container()
.BDDfy();
}

private void ThenTheDangerousAcceptAnyServerCertificateValidatorWarningIsLogged()
{
_logger.Verify(x => x.LogWarning($"You have ignored all SSL warnings by using DangerousAcceptAnyServerCertificateValidator for this DownstreamReRoute, UpstreamPathTemplate: {_context.DownstreamReRoute.UpstreamPathTemplate}, DownstreamPathTemplate: {_context.DownstreamReRoute.DownstreamPathTemplate}"), Times.Once);
}

private void GivenTheClientIsCached()
{
_cacheHandlers.Setup(x => x.Get(It.IsAny<string>())).Returns(_httpClient);
Expand Down

0 comments on commit 636d116

Please sign in to comment.