mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:42:50 +08:00
commit
c11321bb57
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.26228.4
|
VisualStudioVersion = 15.0.26730.15
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5CFB79B7-C9DC-45A4-9A75-625D92471702}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5CFB79B7-C9DC-45A4-9A75-625D92471702}"
|
||||||
EndProject
|
EndProject
|
||||||
@ -12,9 +12,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
build-and-run-tests.ps1 = build-and-run-tests.ps1
|
build-and-run-tests.ps1 = build-and-run-tests.ps1
|
||||||
build.cake = build.cake
|
build.cake = build.cake
|
||||||
build.ps1 = build.ps1
|
build.ps1 = build.ps1
|
||||||
build.readme.md = build.readme.md
|
|
||||||
configuration-explanation.txt = configuration-explanation.txt
|
|
||||||
configuration.yaml = configuration.yaml
|
|
||||||
GitVersion.yml = GitVersion.yml
|
GitVersion.yml = GitVersion.yml
|
||||||
global.json = global.json
|
global.json = global.json
|
||||||
LICENSE.md = LICENSE.md
|
LICENSE.md = LICENSE.md
|
||||||
@ -84,4 +81,7 @@ Global
|
|||||||
{106B49E6-95F6-4A7B-B81C-96BFA74AF035} = {5B401523-36DA-4491-B73A-7590A26E420B}
|
{106B49E6-95F6-4A7B-B81C-96BFA74AF035} = {5B401523-36DA-4491-B73A-7590A26E420B}
|
||||||
{D4575572-99CA-4530-8737-C296EDA326F8} = {5B401523-36DA-4491-B73A-7590A26E420B}
|
{D4575572-99CA-4530-8737-C296EDA326F8} = {5B401523-36DA-4491-B73A-7590A26E420B}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {21476EFF-778A-4F97-8A56-D1AF1CEC0C48}
|
||||||
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@ -33,7 +33,7 @@ That is basically it with a bunch of other features.
|
|||||||
## How to install
|
## How to install
|
||||||
|
|
||||||
Ocelot is designed to work with ASP.NET core only and is currently
|
Ocelot is designed to work with ASP.NET core only and is currently
|
||||||
built to netcoreapp1.1 [this](https://docs.microsoft.com/en-us/dotnet/articles/standard/library) documentation may prove helpful when working out if Ocelot would be suitable for you.
|
built to netcoreapp2.0 [this](https://docs.microsoft.com/en-us/dotnet/articles/standard/library) documentation may prove helpful when working out if Ocelot would be suitable for you.
|
||||||
|
|
||||||
Install Ocelot and it's dependencies using NuGet.
|
Install Ocelot and it's dependencies using NuGet.
|
||||||
|
|
||||||
|
60
build.cake
60
build.cake
@ -1,6 +1,7 @@
|
|||||||
#tool "nuget:?package=GitVersion.CommandLine"
|
#tool "nuget:?package=GitVersion.CommandLine"
|
||||||
#tool "nuget:?package=GitReleaseNotes"
|
#tool "nuget:?package=GitReleaseNotes"
|
||||||
#addin "nuget:?package=Cake.Json"
|
#addin nuget:?package=Cake.Json
|
||||||
|
#addin nuget:?package=Newtonsoft.Json&version=9.0.1
|
||||||
#tool "nuget:?package=OpenCover"
|
#tool "nuget:?package=OpenCover"
|
||||||
#tool "nuget:?package=ReportGenerator"
|
#tool "nuget:?package=ReportGenerator"
|
||||||
#tool coveralls.net
|
#tool coveralls.net
|
||||||
@ -260,11 +261,19 @@ Task("ReleasePackagesToUnstableFeed")
|
|||||||
Task("EnsureStableReleaseRequirements")
|
Task("EnsureStableReleaseRequirements")
|
||||||
.Does(() =>
|
.Does(() =>
|
||||||
{
|
{
|
||||||
|
Information("Check if stable release...");
|
||||||
|
|
||||||
if (!AppVeyor.IsRunningOnAppVeyor)
|
if (!AppVeyor.IsRunningOnAppVeyor)
|
||||||
{
|
{
|
||||||
throw new Exception("Stable release should happen via appveyor");
|
throw new Exception("Stable release should happen via appveyor");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Information("Running on AppVeyor...");
|
||||||
|
|
||||||
|
Information("IsTag = " + AppVeyor.Environment.Repository.Tag.IsTag);
|
||||||
|
|
||||||
|
Information("Name = " + AppVeyor.Environment.Repository.Tag.Name);
|
||||||
|
|
||||||
var isTag =
|
var isTag =
|
||||||
AppVeyor.Environment.Repository.Tag.IsTag &&
|
AppVeyor.Environment.Repository.Tag.IsTag &&
|
||||||
!string.IsNullOrWhiteSpace(AppVeyor.Environment.Repository.Tag.Name);
|
!string.IsNullOrWhiteSpace(AppVeyor.Environment.Repository.Tag.Name);
|
||||||
@ -273,6 +282,8 @@ Task("EnsureStableReleaseRequirements")
|
|||||||
{
|
{
|
||||||
throw new Exception("Stable release should happen from a published GitHub release");
|
throw new Exception("Stable release should happen from a published GitHub release");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Information("Release is stable...");
|
||||||
});
|
});
|
||||||
|
|
||||||
Task("UpdateVersionInfo")
|
Task("UpdateVersionInfo")
|
||||||
@ -287,19 +298,48 @@ Task("DownloadGitHubReleaseArtifacts")
|
|||||||
.IsDependentOn("UpdateVersionInfo")
|
.IsDependentOn("UpdateVersionInfo")
|
||||||
.Does(() =>
|
.Does(() =>
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Information("DownloadGitHubReleaseArtifacts");
|
||||||
|
|
||||||
EnsureDirectoryExists(packagesDir);
|
EnsureDirectoryExists(packagesDir);
|
||||||
|
|
||||||
|
Information("Directory exists...");
|
||||||
|
|
||||||
var releaseUrl = tagsUrl + releaseTag;
|
var releaseUrl = tagsUrl + releaseTag;
|
||||||
var assets_url = ParseJson(GetResource(releaseUrl))
|
|
||||||
|
Information("Release url " + releaseUrl);
|
||||||
|
|
||||||
|
//var releaseJson = Newtonsoft.Json.Linq.JObject.Parse(GetResource(releaseUrl));
|
||||||
|
|
||||||
|
var assets_url = Newtonsoft.Json.Linq.JObject.Parse(GetResource(releaseUrl))
|
||||||
.GetValue("assets_url")
|
.GetValue("assets_url")
|
||||||
.Value<string>();
|
.Value<string>();
|
||||||
|
|
||||||
foreach(var asset in DeserializeJson<JArray>(GetResource(assets_url)))
|
Information("Assets url " + assets_url);
|
||||||
|
|
||||||
|
var assets = GetResource(assets_url);
|
||||||
|
|
||||||
|
Information("Assets " + assets_url);
|
||||||
|
|
||||||
|
foreach(var asset in Newtonsoft.Json.JsonConvert.DeserializeObject<JArray>(assets))
|
||||||
{
|
{
|
||||||
|
Information("In the loop..");
|
||||||
|
|
||||||
var file = packagesDir + File(asset.Value<string>("name"));
|
var file = packagesDir + File(asset.Value<string>("name"));
|
||||||
|
|
||||||
Information("Downloading " + file);
|
Information("Downloading " + file);
|
||||||
|
|
||||||
DownloadFile(asset.Value<string>("browser_download_url"), file);
|
DownloadFile(asset.Value<string>("browser_download_url"), file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Information("Out of the loop...");
|
||||||
|
}
|
||||||
|
catch(Exception exception)
|
||||||
|
{
|
||||||
|
Information("There was an exception " + exception);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Task("ReleasePackagesToStableFeed")
|
Task("ReleasePackagesToStableFeed")
|
||||||
@ -393,6 +433,8 @@ private void PublishPackages(ConvertableDirectoryPath packagesDir, ConvertableFi
|
|||||||
|
|
||||||
/// gets the resource from the specified url
|
/// gets the resource from the specified url
|
||||||
private string GetResource(string url)
|
private string GetResource(string url)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
Information("Getting resource from " + url);
|
Information("Getting resource from " + url);
|
||||||
|
|
||||||
@ -405,7 +447,17 @@ private string GetResource(string url)
|
|||||||
{
|
{
|
||||||
var assetsStream = assetsResponse.GetResponseStream();
|
var assetsStream = assetsResponse.GetResponseStream();
|
||||||
var assetsReader = new StreamReader(assetsStream);
|
var assetsReader = new StreamReader(assetsStream);
|
||||||
return assetsReader.ReadToEnd();
|
var response = assetsReader.ReadToEnd();
|
||||||
|
|
||||||
|
Information("Response is " + response);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception exception)
|
||||||
|
{
|
||||||
|
Information("There was an exception " + exception);
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
117
build.ps1
117
build.ps1
@ -21,34 +21,35 @@ The build script target to run.
|
|||||||
The build configuration to use.
|
The build configuration to use.
|
||||||
.PARAMETER Verbosity
|
.PARAMETER Verbosity
|
||||||
Specifies the amount of information to be displayed.
|
Specifies the amount of information to be displayed.
|
||||||
|
.PARAMETER ShowDescription
|
||||||
|
Shows description about tasks.
|
||||||
|
.PARAMETER DryRun
|
||||||
|
Performs a dry run.
|
||||||
.PARAMETER Experimental
|
.PARAMETER Experimental
|
||||||
Tells Cake to use the latest Roslyn release.
|
Uses the nightly builds of the Roslyn script engine.
|
||||||
.PARAMETER WhatIf
|
|
||||||
Performs a dry run of the build script.
|
|
||||||
No tasks will be executed.
|
|
||||||
.PARAMETER Mono
|
.PARAMETER Mono
|
||||||
Tells Cake to use the Mono scripting engine.
|
Uses the Mono Compiler rather than the Roslyn script engine.
|
||||||
.PARAMETER SkipToolPackageRestore
|
.PARAMETER SkipToolPackageRestore
|
||||||
Skips restoring of packages.
|
Skips restoring of packages.
|
||||||
.PARAMETER ScriptArgs
|
.PARAMETER ScriptArgs
|
||||||
Remaining arguments are added here.
|
Remaining arguments are added here.
|
||||||
|
|
||||||
.LINK
|
.LINK
|
||||||
http://cakebuild.net
|
https://cakebuild.net
|
||||||
|
|
||||||
#>
|
#>
|
||||||
|
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
Param(
|
Param(
|
||||||
[string]$Script = "build.cake",
|
[string]$Script = "build.cake",
|
||||||
[string]$Target = "Default",
|
[string]$Target,
|
||||||
[ValidateSet("Release", "Debug")]
|
[string]$Configuration,
|
||||||
[string]$Configuration = "Release",
|
|
||||||
[ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")]
|
[ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")]
|
||||||
[string]$Verbosity = "Verbose",
|
[string]$Verbosity,
|
||||||
|
[switch]$ShowDescription,
|
||||||
|
[Alias("WhatIf", "Noop")]
|
||||||
|
[switch]$DryRun,
|
||||||
[switch]$Experimental,
|
[switch]$Experimental,
|
||||||
[Alias("DryRun","Noop")]
|
|
||||||
[switch]$WhatIf,
|
|
||||||
[switch]$Mono,
|
[switch]$Mono,
|
||||||
[switch]$SkipToolPackageRestore,
|
[switch]$SkipToolPackageRestore,
|
||||||
[Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
|
[Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
|
||||||
@ -80,6 +81,15 @@ function MD5HashFile([string] $filePath)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function GetProxyEnabledWebClient
|
||||||
|
{
|
||||||
|
$wc = New-Object System.Net.WebClient
|
||||||
|
$proxy = [System.Net.WebRequest]::GetSystemWebProxy()
|
||||||
|
$proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
|
||||||
|
$wc.Proxy = $proxy
|
||||||
|
return $wc
|
||||||
|
}
|
||||||
|
|
||||||
Write-Host "Preparing to run build script..."
|
Write-Host "Preparing to run build script..."
|
||||||
|
|
||||||
if(!$PSScriptRoot){
|
if(!$PSScriptRoot){
|
||||||
@ -87,31 +97,15 @@ if(!$PSScriptRoot){
|
|||||||
}
|
}
|
||||||
|
|
||||||
$TOOLS_DIR = Join-Path $PSScriptRoot "tools"
|
$TOOLS_DIR = Join-Path $PSScriptRoot "tools"
|
||||||
|
$ADDINS_DIR = Join-Path $TOOLS_DIR "Addins"
|
||||||
|
$MODULES_DIR = Join-Path $TOOLS_DIR "Modules"
|
||||||
$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe"
|
$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe"
|
||||||
$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe"
|
$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe"
|
||||||
$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
|
$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
|
||||||
$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config"
|
$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config"
|
||||||
$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum"
|
$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum"
|
||||||
|
$ADDINS_PACKAGES_CONFIG = Join-Path $ADDINS_DIR "packages.config"
|
||||||
# Should we use mono?
|
$MODULES_PACKAGES_CONFIG = Join-Path $MODULES_DIR "packages.config"
|
||||||
$UseMono = "";
|
|
||||||
if($Mono.IsPresent) {
|
|
||||||
Write-Verbose -Message "Using the Mono based scripting engine."
|
|
||||||
$UseMono = "-mono"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Should we use the new Roslyn?
|
|
||||||
$UseExperimental = "";
|
|
||||||
if($Experimental.IsPresent -and !($Mono.IsPresent)) {
|
|
||||||
Write-Verbose -Message "Using experimental version of Roslyn."
|
|
||||||
$UseExperimental = "-experimental"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Is this a dry run?
|
|
||||||
$UseDryRun = "";
|
|
||||||
if($WhatIf.IsPresent) {
|
|
||||||
$UseDryRun = "-dryrun"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Make sure tools folder exists
|
# Make sure tools folder exists
|
||||||
if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {
|
if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {
|
||||||
@ -122,7 +116,9 @@ if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {
|
|||||||
# Make sure that packages.config exist.
|
# Make sure that packages.config exist.
|
||||||
if (!(Test-Path $PACKAGES_CONFIG)) {
|
if (!(Test-Path $PACKAGES_CONFIG)) {
|
||||||
Write-Verbose -Message "Downloading packages.config..."
|
Write-Verbose -Message "Downloading packages.config..."
|
||||||
try { (New-Object System.Net.WebClient).DownloadFile("http://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch {
|
try {
|
||||||
|
$wc = GetProxyEnabledWebClient
|
||||||
|
$wc.DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch {
|
||||||
Throw "Could not download packages.config."
|
Throw "Could not download packages.config."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,7 +126,7 @@ if (!(Test-Path $PACKAGES_CONFIG)) {
|
|||||||
# Try find NuGet.exe in path if not exists
|
# Try find NuGet.exe in path if not exists
|
||||||
if (!(Test-Path $NUGET_EXE)) {
|
if (!(Test-Path $NUGET_EXE)) {
|
||||||
Write-Verbose -Message "Trying to find nuget.exe in PATH..."
|
Write-Verbose -Message "Trying to find nuget.exe in PATH..."
|
||||||
$existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_) }
|
$existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_ -PathType Container) }
|
||||||
$NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1
|
$NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1
|
||||||
if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) {
|
if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) {
|
||||||
Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)."
|
Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)."
|
||||||
@ -142,7 +138,8 @@ if (!(Test-Path $NUGET_EXE)) {
|
|||||||
if (!(Test-Path $NUGET_EXE)) {
|
if (!(Test-Path $NUGET_EXE)) {
|
||||||
Write-Verbose -Message "Downloading NuGet.exe..."
|
Write-Verbose -Message "Downloading NuGet.exe..."
|
||||||
try {
|
try {
|
||||||
(New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE)
|
$wc = GetProxyEnabledWebClient
|
||||||
|
$wc.DownloadFile($NUGET_URL, $NUGET_EXE)
|
||||||
} catch {
|
} catch {
|
||||||
Throw "Could not download NuGet.exe."
|
Throw "Could not download NuGet.exe."
|
||||||
}
|
}
|
||||||
@ -175,6 +172,41 @@ if(-Not $SkipToolPackageRestore.IsPresent) {
|
|||||||
$md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII"
|
$md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII"
|
||||||
}
|
}
|
||||||
Write-Verbose -Message ($NuGetOutput | out-string)
|
Write-Verbose -Message ($NuGetOutput | out-string)
|
||||||
|
|
||||||
|
Pop-Location
|
||||||
|
}
|
||||||
|
|
||||||
|
# Restore addins from NuGet
|
||||||
|
if (Test-Path $ADDINS_PACKAGES_CONFIG) {
|
||||||
|
Push-Location
|
||||||
|
Set-Location $ADDINS_DIR
|
||||||
|
|
||||||
|
Write-Verbose -Message "Restoring addins from NuGet..."
|
||||||
|
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$ADDINS_DIR`""
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Throw "An error occured while restoring NuGet addins."
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Verbose -Message ($NuGetOutput | out-string)
|
||||||
|
|
||||||
|
Pop-Location
|
||||||
|
}
|
||||||
|
|
||||||
|
# Restore modules from NuGet
|
||||||
|
if (Test-Path $MODULES_PACKAGES_CONFIG) {
|
||||||
|
Push-Location
|
||||||
|
Set-Location $MODULES_DIR
|
||||||
|
|
||||||
|
Write-Verbose -Message "Restoring modules from NuGet..."
|
||||||
|
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$MODULES_DIR`""
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Throw "An error occured while restoring NuGet modules."
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Verbose -Message ($NuGetOutput | out-string)
|
||||||
|
|
||||||
Pop-Location
|
Pop-Location
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +215,20 @@ if (!(Test-Path $CAKE_EXE)) {
|
|||||||
Throw "Could not find Cake.exe at $CAKE_EXE"
|
Throw "Could not find Cake.exe at $CAKE_EXE"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Build Cake arguments
|
||||||
|
$cakeArguments = @("$Script");
|
||||||
|
if ($Target) { $cakeArguments += "-target=$Target" }
|
||||||
|
if ($Configuration) { $cakeArguments += "-configuration=$Configuration" }
|
||||||
|
if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" }
|
||||||
|
if ($ShowDescription) { $cakeArguments += "-showdescription" }
|
||||||
|
if ($DryRun) { $cakeArguments += "-dryrun" }
|
||||||
|
if ($Experimental) { $cakeArguments += "-experimental" }
|
||||||
|
if ($Mono) { $cakeArguments += "-mono" }
|
||||||
|
$cakeArguments += $ScriptArgs
|
||||||
|
|
||||||
# Start Cake
|
# Start Cake
|
||||||
Write-Host "Running build script..."
|
Write-Host "Running build script..."
|
||||||
Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseMono $UseDryRun $UseExperimental $ScriptArgs"
|
&$CAKE_EXE $cakeArguments
|
||||||
exit $LASTEXITCODE
|
exit $LASTEXITCODE
|
@ -1 +1,6 @@
|
|||||||
{"projects":["src","test"]}
|
{
|
||||||
|
"projects": [ "src", "test" ],
|
||||||
|
"sdk": {
|
||||||
|
"version": "2.0.0"
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +0,0 @@
|
|||||||
namespace Ocelot.Authentication.Handler
|
|
||||||
{
|
|
||||||
public class AuthenticationHandler
|
|
||||||
{
|
|
||||||
public AuthenticationHandler(string provider, IHandler handler)
|
|
||||||
{
|
|
||||||
Provider = provider;
|
|
||||||
Handler = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Provider { get; private set; }
|
|
||||||
public IHandler Handler { get; private set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
using System;
|
|
||||||
using IdentityServer4.AccessTokenValidation;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Ocelot.Responses;
|
|
||||||
|
|
||||||
namespace Ocelot.Authentication.Handler.Creator
|
|
||||||
{
|
|
||||||
using Ocelot.Configuration;
|
|
||||||
|
|
||||||
using AuthenticationOptions = Configuration.AuthenticationOptions;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Cannot unit test things in this class due to use of extension methods
|
|
||||||
/// </summary>
|
|
||||||
public class AuthenticationHandlerCreator : IAuthenticationHandlerCreator
|
|
||||||
{
|
|
||||||
public Response<RequestDelegate> Create(IApplicationBuilder app, AuthenticationOptions authOptions)
|
|
||||||
{
|
|
||||||
var builder = app.New();
|
|
||||||
|
|
||||||
if (authOptions.Provider.ToLower() == "jwt")
|
|
||||||
{
|
|
||||||
var authenticationConfig = authOptions.Config as JwtConfig;
|
|
||||||
|
|
||||||
builder.UseJwtBearerAuthentication(
|
|
||||||
new JwtBearerOptions()
|
|
||||||
{
|
|
||||||
Authority = authenticationConfig.Authority,
|
|
||||||
Audience = authenticationConfig.Audience
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var authenticationConfig = authOptions.Config as IdentityServerConfig;
|
|
||||||
|
|
||||||
builder.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
|
|
||||||
{
|
|
||||||
Authority = authenticationConfig.ProviderRootUrl,
|
|
||||||
ApiName = authenticationConfig.ApiName,
|
|
||||||
RequireHttpsMetadata = authenticationConfig.RequireHttps,
|
|
||||||
AllowedScopes = authOptions.AllowedScopes,
|
|
||||||
SupportedTokens = SupportedTokens.Both,
|
|
||||||
ApiSecret = authenticationConfig.ApiSecret
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var authenticationNext = builder.Build();
|
|
||||||
|
|
||||||
return new OkResponse<RequestDelegate>(authenticationNext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Ocelot.Responses;
|
|
||||||
|
|
||||||
namespace Ocelot.Authentication.Handler.Creator
|
|
||||||
{
|
|
||||||
using AuthenticationOptions = Configuration.AuthenticationOptions;
|
|
||||||
|
|
||||||
public interface IAuthenticationHandlerCreator
|
|
||||||
{
|
|
||||||
Response<RequestDelegate> Create(IApplicationBuilder app, AuthenticationOptions authOptions);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Ocelot.Authentication.Handler.Creator;
|
|
||||||
using Ocelot.Errors;
|
|
||||||
using Ocelot.Responses;
|
|
||||||
|
|
||||||
namespace Ocelot.Authentication.Handler.Factory
|
|
||||||
{
|
|
||||||
using AuthenticationOptions = Configuration.AuthenticationOptions;
|
|
||||||
|
|
||||||
public class AuthenticationHandlerFactory : IAuthenticationHandlerFactory
|
|
||||||
{
|
|
||||||
private readonly IAuthenticationHandlerCreator _creator;
|
|
||||||
|
|
||||||
public AuthenticationHandlerFactory(IAuthenticationHandlerCreator creator)
|
|
||||||
{
|
|
||||||
_creator = creator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Response<AuthenticationHandler> Get(IApplicationBuilder app, AuthenticationOptions authOptions)
|
|
||||||
{
|
|
||||||
var handler = _creator.Create(app, authOptions);
|
|
||||||
|
|
||||||
if (!handler.IsError)
|
|
||||||
{
|
|
||||||
return new OkResponse<AuthenticationHandler>(
|
|
||||||
new AuthenticationHandler(authOptions.Provider, new RequestDelegateHandler(handler.Data)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ErrorResponse<AuthenticationHandler>(new List<Error>
|
|
||||||
{
|
|
||||||
new UnableToCreateAuthenticationHandlerError($"Unable to create authentication handler for {authOptions.Provider}")
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Ocelot.Responses;
|
|
||||||
|
|
||||||
namespace Ocelot.Authentication.Handler.Factory
|
|
||||||
{
|
|
||||||
using AuthenticationOptions = Configuration.AuthenticationOptions;
|
|
||||||
|
|
||||||
public interface IAuthenticationHandlerFactory
|
|
||||||
{
|
|
||||||
Response<AuthenticationHandler> Get(IApplicationBuilder app, AuthenticationOptions authOptions);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
using Ocelot.Errors;
|
|
||||||
|
|
||||||
namespace Ocelot.Authentication.Handler.Factory
|
|
||||||
{
|
|
||||||
public class UnableToCreateAuthenticationHandlerError : Error
|
|
||||||
{
|
|
||||||
public UnableToCreateAuthenticationHandlerError(string message)
|
|
||||||
: base(message, OcelotErrorCode.UnableToCreateAuthenticationHandlerError)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
|
|
||||||
namespace Ocelot.Authentication.Handler
|
|
||||||
{
|
|
||||||
public interface IHandler
|
|
||||||
{
|
|
||||||
Task Handle(HttpContext context);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
|
|
||||||
namespace Ocelot.Authentication.Handler
|
|
||||||
{
|
|
||||||
public class RequestDelegateHandler : IHandler
|
|
||||||
{
|
|
||||||
private readonly RequestDelegate _requestDelegate;
|
|
||||||
|
|
||||||
public RequestDelegateHandler(RequestDelegate requestDelegate)
|
|
||||||
{
|
|
||||||
_requestDelegate = requestDelegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Handle(HttpContext context)
|
|
||||||
{
|
|
||||||
await _requestDelegate.Invoke(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Ocelot.Configuration;
|
|
||||||
|
|
||||||
namespace Ocelot.Authentication.JsonConverters
|
|
||||||
{
|
|
||||||
public class AuthenticationConfigConverter : JsonConverter
|
|
||||||
{
|
|
||||||
public override bool CanWrite => false;
|
|
||||||
|
|
||||||
public override bool CanRead => true;
|
|
||||||
|
|
||||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Use default serialization.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
|
||||||
{
|
|
||||||
var jsonObject = JObject.Load(reader);
|
|
||||||
var setting = default(IAuthenticationConfig);
|
|
||||||
|
|
||||||
if (jsonObject["Provider"] != null)
|
|
||||||
{
|
|
||||||
switch (jsonObject["Provider"].Value<string>())
|
|
||||||
{
|
|
||||||
case "Jwt":
|
|
||||||
setting = new JwtConfig(
|
|
||||||
jsonObject["Authority"].Value<string>(),
|
|
||||||
jsonObject["Audience"].Value<string>());
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
setting = new IdentityServerConfig(
|
|
||||||
jsonObject["ProviderRootUrl"].Value<string>(),
|
|
||||||
jsonObject["ApiName"].Value<string>(),
|
|
||||||
jsonObject["RequireHttps"].Value<bool>(),
|
|
||||||
jsonObject["ApiSecret"].Value<string>());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setting = new IdentityServerConfig(string.Empty, string.Empty, false, string.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
serializer.Populate(jsonObject.CreateReader(), setting);
|
|
||||||
return setting;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool CanConvert(Type objectType)
|
|
||||||
{
|
|
||||||
return objectType == typeof(IAuthenticationConfig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,8 +1,8 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Authentication.Handler.Factory;
|
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
using Ocelot.Errors;
|
using Ocelot.Errors;
|
||||||
using Ocelot.Infrastructure.Extensions;
|
using Ocelot.Infrastructure.Extensions;
|
||||||
@ -16,18 +16,16 @@ namespace Ocelot.Authentication.Middleware
|
|||||||
{
|
{
|
||||||
private readonly RequestDelegate _next;
|
private readonly RequestDelegate _next;
|
||||||
private readonly IApplicationBuilder _app;
|
private readonly IApplicationBuilder _app;
|
||||||
private readonly IAuthenticationHandlerFactory _authHandlerFactory;
|
private readonly IAuthenticationSchemeProvider _authSchemeProvider;
|
||||||
private readonly IOcelotLogger _logger;
|
private readonly IOcelotLogger _logger;
|
||||||
|
|
||||||
public AuthenticationMiddleware(RequestDelegate next,
|
public AuthenticationMiddleware(RequestDelegate next,
|
||||||
IApplicationBuilder app,
|
IApplicationBuilder app,
|
||||||
IRequestScopedDataRepository requestScopedDataRepository,
|
IRequestScopedDataRepository requestScopedDataRepository,
|
||||||
IAuthenticationHandlerFactory authHandlerFactory,
|
|
||||||
IOcelotLoggerFactory loggerFactory)
|
IOcelotLoggerFactory loggerFactory)
|
||||||
: base(requestScopedDataRepository)
|
: base(requestScopedDataRepository)
|
||||||
{
|
{
|
||||||
_next = next;
|
_next = next;
|
||||||
_authHandlerFactory = authHandlerFactory;
|
|
||||||
_app = app;
|
_app = app;
|
||||||
_logger = loggerFactory.CreateLogger<AuthenticationMiddleware>();
|
_logger = loggerFactory.CreateLogger<AuthenticationMiddleware>();
|
||||||
}
|
}
|
||||||
@ -38,17 +36,9 @@ namespace Ocelot.Authentication.Middleware
|
|||||||
{
|
{
|
||||||
_logger.LogDebug($"{context.Request.Path} is an authenticated route. {MiddlewareName} checking if client is authenticated");
|
_logger.LogDebug($"{context.Request.Path} is an authenticated route. {MiddlewareName} checking if client is authenticated");
|
||||||
|
|
||||||
var authenticationHandler = _authHandlerFactory.Get(_app, DownstreamRoute.ReRoute.AuthenticationOptions);
|
var result = await context.AuthenticateAsync(DownstreamRoute.ReRoute.AuthenticationOptions.AuthenticationProviderKey);
|
||||||
|
|
||||||
if (authenticationHandler.IsError)
|
|
||||||
{
|
|
||||||
_logger.LogError($"Error getting authentication handler for {context.Request.Path}. {authenticationHandler.Errors.ToErrorString()}");
|
|
||||||
SetPipelineError(authenticationHandler.Errors);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await authenticationHandler.Data.Handler.Handle(context);
|
|
||||||
|
|
||||||
|
context.User = result.Principal;
|
||||||
|
|
||||||
if (context.User.Identity.IsAuthenticated)
|
if (context.User.Identity.IsAuthenticated)
|
||||||
{
|
{
|
||||||
@ -65,7 +55,6 @@ namespace Ocelot.Authentication.Middleware
|
|||||||
|
|
||||||
_logger.LogError($"Client has NOT been authenticated for {context.Request.Path} and pipeline error set. {error.ToErrorString()}");
|
_logger.LogError($"Client has NOT been authenticated for {context.Request.Path} and pipeline error set. {error.ToErrorString()}");
|
||||||
SetPipelineError(error);
|
SetPipelineError(error);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2,52 +2,15 @@
|
|||||||
|
|
||||||
namespace Ocelot.Configuration
|
namespace Ocelot.Configuration
|
||||||
{
|
{
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
public class AuthenticationOptions
|
public class AuthenticationOptions
|
||||||
{
|
{
|
||||||
public AuthenticationOptions(string provider, List<string> allowedScopes, IAuthenticationConfig config)
|
public AuthenticationOptions(List<string> allowedScopes, string authenticationProviderKey)
|
||||||
{
|
{
|
||||||
Provider = provider;
|
|
||||||
AllowedScopes = allowedScopes;
|
AllowedScopes = allowedScopes;
|
||||||
Config = config;
|
AuthenticationProviderKey = authenticationProviderKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Provider { get; private set; }
|
|
||||||
|
|
||||||
public List<string> AllowedScopes { get; private set; }
|
public List<string> AllowedScopes { get; private set; }
|
||||||
|
public string AuthenticationProviderKey { get; private set; }
|
||||||
public IAuthenticationConfig Config { get; private set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class IdentityServerConfig : IAuthenticationConfig
|
|
||||||
{
|
|
||||||
public IdentityServerConfig(string providerRootUrl, string apiName, bool requireHttps, string apiSecret)
|
|
||||||
{
|
|
||||||
ProviderRootUrl = providerRootUrl;
|
|
||||||
ApiName = apiName;
|
|
||||||
RequireHttps = requireHttps;
|
|
||||||
ApiSecret = apiSecret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ProviderRootUrl { get; private set; }
|
|
||||||
public string ApiName { get; private set; }
|
|
||||||
public string ApiSecret { get; private set; }
|
|
||||||
public bool RequireHttps { get; private set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class JwtConfig : IAuthenticationConfig
|
|
||||||
{
|
|
||||||
public JwtConfig(string authority, string audience)
|
|
||||||
{
|
|
||||||
Audience = audience;
|
|
||||||
Authority = authority;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Audience { get; }
|
|
||||||
|
|
||||||
public string Authority { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IAuthenticationConfig {}
|
|
||||||
}
|
}
|
||||||
|
@ -4,18 +4,8 @@ namespace Ocelot.Configuration.Builder
|
|||||||
{
|
{
|
||||||
public class AuthenticationOptionsBuilder
|
public class AuthenticationOptionsBuilder
|
||||||
{
|
{
|
||||||
|
private List<string> _allowedScopes = new List<string>();
|
||||||
private string _provider;
|
private string _authenticationProviderKey;
|
||||||
|
|
||||||
private List<string> _allowedScopes;
|
|
||||||
|
|
||||||
private IAuthenticationConfig _identityServerConfig;
|
|
||||||
|
|
||||||
public AuthenticationOptionsBuilder WithProvider(string provider)
|
|
||||||
{
|
|
||||||
_provider = provider;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationOptionsBuilder WithAllowedScopes(List<string> allowedScopes)
|
public AuthenticationOptionsBuilder WithAllowedScopes(List<string> allowedScopes)
|
||||||
{
|
{
|
||||||
@ -23,76 +13,15 @@ namespace Ocelot.Configuration.Builder
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthenticationOptionsBuilder WithConfig(IAuthenticationConfig config)
|
public AuthenticationOptionsBuilder WithAuthenticationProviderKey(string authenticationProviderKey)
|
||||||
{
|
{
|
||||||
_identityServerConfig = config;
|
_authenticationProviderKey = authenticationProviderKey;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthenticationOptions Build()
|
public AuthenticationOptions Build()
|
||||||
{
|
{
|
||||||
return new AuthenticationOptions(_provider, _allowedScopes, _identityServerConfig);
|
return new AuthenticationOptions(_allowedScopes, _authenticationProviderKey);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class IdentityServerConfigBuilder
|
|
||||||
{
|
|
||||||
private string _providerRootUrl;
|
|
||||||
private string _apiName;
|
|
||||||
private string _apiSecret;
|
|
||||||
private bool _requireHttps;
|
|
||||||
|
|
||||||
public IdentityServerConfigBuilder WithProviderRootUrl(string providerRootUrl)
|
|
||||||
{
|
|
||||||
_providerRootUrl = providerRootUrl;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IdentityServerConfigBuilder WithApiName(string apiName)
|
|
||||||
{
|
|
||||||
_apiName = apiName;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IdentityServerConfigBuilder WithApiSecret(string apiSecret)
|
|
||||||
{
|
|
||||||
_apiSecret = apiSecret;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IdentityServerConfigBuilder WithRequireHttps(bool requireHttps)
|
|
||||||
{
|
|
||||||
_requireHttps = requireHttps;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IdentityServerConfig Build()
|
|
||||||
{
|
|
||||||
return new IdentityServerConfig(_providerRootUrl, _apiName, _requireHttps, _apiSecret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class JwtConfigBuilder
|
|
||||||
{
|
|
||||||
public string _authority;
|
|
||||||
|
|
||||||
public string _audience;
|
|
||||||
|
|
||||||
public JwtConfigBuilder WithAuthority(string authority)
|
|
||||||
{
|
|
||||||
_authority = authority;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JwtConfigBuilder WithAudience(string audience)
|
|
||||||
{
|
|
||||||
_audience = audience;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JwtConfig Build()
|
|
||||||
{
|
|
||||||
return new JwtConfig(_authority, _audience);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -29,8 +29,10 @@ namespace Ocelot.Configuration.Builder
|
|||||||
private ServiceProviderConfiguration _serviceProviderConfiguraion;
|
private ServiceProviderConfiguration _serviceProviderConfiguraion;
|
||||||
private bool _useQos;
|
private bool _useQos;
|
||||||
private QoSOptions _qosOptions;
|
private QoSOptions _qosOptions;
|
||||||
|
private HttpHandlerOptions _httpHandlerOptions;
|
||||||
public bool _enableRateLimiting;
|
public bool _enableRateLimiting;
|
||||||
public RateLimitOptions _rateLimitOptions;
|
public RateLimitOptions _rateLimitOptions;
|
||||||
|
private string _authenticationProviderKey;
|
||||||
|
|
||||||
public ReRouteBuilder WithLoadBalancer(string loadBalancer)
|
public ReRouteBuilder WithLoadBalancer(string loadBalancer)
|
||||||
{
|
{
|
||||||
@ -176,6 +178,17 @@ namespace Ocelot.Configuration.Builder
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ReRouteBuilder WithAuthenticationProviderKey(string authenticationProviderKey)
|
||||||
|
{
|
||||||
|
_authenticationProviderKey = authenticationProviderKey;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReRouteBuilder WithHttpHandlerOptions(HttpHandlerOptions input)
|
||||||
|
{
|
||||||
|
_httpHandlerOptions = input;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public ReRoute Build()
|
public ReRoute Build()
|
||||||
{
|
{
|
||||||
@ -203,7 +216,8 @@ namespace Ocelot.Configuration.Builder
|
|||||||
_useQos,
|
_useQos,
|
||||||
_qosOptions,
|
_qosOptions,
|
||||||
_enableRateLimiting,
|
_enableRateLimiting,
|
||||||
_rateLimitOptions);
|
_rateLimitOptions,
|
||||||
|
_httpHandlerOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,12 @@
|
|||||||
using Ocelot.Configuration.Builder;
|
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Creator.Configuration;
|
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Creator
|
namespace Ocelot.Configuration.Creator
|
||||||
{
|
{
|
||||||
public class AuthenticationOptionsCreator : IAuthenticationOptionsCreator
|
public class AuthenticationOptionsCreator : IAuthenticationOptionsCreator
|
||||||
{
|
{
|
||||||
private readonly IAuthenticationProviderConfigCreator _creator;
|
public AuthenticationOptions Create(FileReRoute reRoute)
|
||||||
|
|
||||||
public AuthenticationOptionsCreator(IAuthenticationProviderConfigCreator creator)
|
|
||||||
{
|
{
|
||||||
_creator = creator;
|
return new AuthenticationOptions(reRoute.AuthenticationOptions.AllowedScopes, reRoute.AuthenticationOptions.AuthenticationProviderKey);
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationOptions Create(FileReRoute fileReRoute)
|
|
||||||
{
|
|
||||||
var authenticationConfig = _creator.Create(fileReRoute.AuthenticationOptions);
|
|
||||||
|
|
||||||
return new AuthenticationOptionsBuilder()
|
|
||||||
.WithProvider(fileReRoute.AuthenticationOptions?.Provider)
|
|
||||||
.WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
|
|
||||||
.WithConfig(authenticationConfig)
|
|
||||||
.Build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,37 +0,0 @@
|
|||||||
using Ocelot.Creator.Configuration;
|
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Creator
|
|
||||||
{
|
|
||||||
using Ocelot.Configuration.Builder;
|
|
||||||
using Ocelot.Configuration.File;
|
|
||||||
|
|
||||||
public class AuthenticationProviderConfigCreator : IAuthenticationProviderConfigCreator
|
|
||||||
{
|
|
||||||
public IAuthenticationConfig Create(FileAuthenticationOptions authenticationOptions)
|
|
||||||
{
|
|
||||||
if (authenticationOptions.Provider?.ToLower() == "jwt")
|
|
||||||
{
|
|
||||||
return CreateJwt(authenticationOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
return CreateIdentityServer(authenticationOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
private JwtConfig CreateJwt(FileAuthenticationOptions authenticationOptions)
|
|
||||||
{
|
|
||||||
return new JwtConfigBuilder()
|
|
||||||
.WithAudience(authenticationOptions.JwtConfig?.Audience)
|
|
||||||
.WithAuthority(authenticationOptions.JwtConfig?.Authority)
|
|
||||||
.Build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private IdentityServerConfig CreateIdentityServer(FileAuthenticationOptions authenticationOptions)
|
|
||||||
{
|
|
||||||
return new IdentityServerConfigBuilder()
|
|
||||||
.WithApiName(authenticationOptions.IdentityServerConfig?.ApiName)
|
|
||||||
.WithApiSecret(authenticationOptions.IdentityServerConfig?.ApiSecret)
|
|
||||||
.WithProviderRootUrl(authenticationOptions.IdentityServerConfig?.ProviderRootUrl)
|
|
||||||
.WithRequireHttps(authenticationOptions.IdentityServerConfig.RequireHttps).Build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -38,6 +38,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
private readonly IReRouteOptionsCreator _fileReRouteOptionsCreator;
|
private readonly IReRouteOptionsCreator _fileReRouteOptionsCreator;
|
||||||
private readonly IRateLimitOptionsCreator _rateLimitOptionsCreator;
|
private readonly IRateLimitOptionsCreator _rateLimitOptionsCreator;
|
||||||
private readonly IRegionCreator _regionCreator;
|
private readonly IRegionCreator _regionCreator;
|
||||||
|
private readonly IHttpHandlerOptionsCreator _httpHandlerOptionsCreator;
|
||||||
|
|
||||||
public FileOcelotConfigurationCreator(
|
public FileOcelotConfigurationCreator(
|
||||||
IOptions<FileConfiguration> options,
|
IOptions<FileConfiguration> options,
|
||||||
@ -55,7 +56,8 @@ namespace Ocelot.Configuration.Creator
|
|||||||
IQoSOptionsCreator qosOptionsCreator,
|
IQoSOptionsCreator qosOptionsCreator,
|
||||||
IReRouteOptionsCreator fileReRouteOptionsCreator,
|
IReRouteOptionsCreator fileReRouteOptionsCreator,
|
||||||
IRateLimitOptionsCreator rateLimitOptionsCreator,
|
IRateLimitOptionsCreator rateLimitOptionsCreator,
|
||||||
IRegionCreator regionCreator
|
IRegionCreator regionCreator,
|
||||||
|
IHttpHandlerOptionsCreator httpHandlerOptionsCreator
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_regionCreator = regionCreator;
|
_regionCreator = regionCreator;
|
||||||
@ -74,6 +76,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
_serviceProviderConfigCreator = serviceProviderConfigCreator;
|
_serviceProviderConfigCreator = serviceProviderConfigCreator;
|
||||||
_qosOptionsCreator = qosOptionsCreator;
|
_qosOptionsCreator = qosOptionsCreator;
|
||||||
_fileReRouteOptionsCreator = fileReRouteOptionsCreator;
|
_fileReRouteOptionsCreator = fileReRouteOptionsCreator;
|
||||||
|
_httpHandlerOptionsCreator = httpHandlerOptionsCreator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Response<IOcelotConfiguration>> Create()
|
public async Task<Response<IOcelotConfiguration>> Create()
|
||||||
@ -92,7 +95,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
|
|
||||||
private async Task<IOcelotConfiguration> SetUpConfiguration(FileConfiguration fileConfiguration)
|
private async Task<IOcelotConfiguration> SetUpConfiguration(FileConfiguration fileConfiguration)
|
||||||
{
|
{
|
||||||
var response = _configurationValidator.IsValid(fileConfiguration);
|
var response = await _configurationValidator.IsValid(fileConfiguration);
|
||||||
|
|
||||||
if (response.Data.IsError)
|
if (response.Data.IsError)
|
||||||
{
|
{
|
||||||
@ -143,6 +146,8 @@ namespace Ocelot.Configuration.Creator
|
|||||||
|
|
||||||
var region = _regionCreator.Create(fileReRoute);
|
var region = _regionCreator.Create(fileReRoute);
|
||||||
|
|
||||||
|
var httpHandlerOptions = _httpHandlerOptionsCreator.Create(fileReRoute);
|
||||||
|
|
||||||
var reRoute = new ReRouteBuilder()
|
var reRoute = new ReRouteBuilder()
|
||||||
.WithDownstreamPathTemplate(fileReRoute.DownstreamPathTemplate)
|
.WithDownstreamPathTemplate(fileReRoute.DownstreamPathTemplate)
|
||||||
.WithUpstreamPathTemplate(fileReRoute.UpstreamPathTemplate)
|
.WithUpstreamPathTemplate(fileReRoute.UpstreamPathTemplate)
|
||||||
@ -168,6 +173,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
.WithQosOptions(qosOptions)
|
.WithQosOptions(qosOptions)
|
||||||
.WithEnableRateLimiting(fileReRouteOptions.EnableRateLimiting)
|
.WithEnableRateLimiting(fileReRouteOptions.EnableRateLimiting)
|
||||||
.WithRateLimitOptions(rateLimitOption)
|
.WithRateLimitOptions(rateLimitOption)
|
||||||
|
.WithHttpHandlerOptions(httpHandlerOptions)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
await SetupLoadBalancer(reRoute);
|
await SetupLoadBalancer(reRoute);
|
||||||
@ -178,7 +184,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
private string CreateReRouteKey(FileReRoute fileReRoute)
|
private string CreateReRouteKey(FileReRoute fileReRoute)
|
||||||
{
|
{
|
||||||
//note - not sure if this is the correct key, but this is probably the only unique key i can think of given my poor brain
|
//note - not sure if this is the correct key, but this is probably the only unique key i can think of given my poor brain
|
||||||
var loadBalancerKey = $"{fileReRoute.UpstreamPathTemplate}{fileReRoute.UpstreamHttpMethod}";
|
var loadBalancerKey = $"{fileReRoute.UpstreamPathTemplate}|{string.Join(",", fileReRoute.UpstreamHttpMethod)}";
|
||||||
return loadBalancerKey;
|
return loadBalancerKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
using Ocelot.Configuration.File;
|
||||||
|
|
||||||
|
namespace Ocelot.Configuration.Creator
|
||||||
|
{
|
||||||
|
public class HttpHandlerOptionsCreator : IHttpHandlerOptionsCreator
|
||||||
|
{
|
||||||
|
public HttpHandlerOptions Create(FileReRoute fileReRoute)
|
||||||
|
{
|
||||||
|
return new HttpHandlerOptions(fileReRoute.HttpHandlerOptions.AllowAutoRedirect,
|
||||||
|
fileReRoute.HttpHandlerOptions.UseCookieContainer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,10 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Creator
|
namespace Ocelot.Configuration.Creator
|
||||||
{
|
{
|
||||||
public interface IAuthenticationOptionsCreator
|
public interface IAuthenticationOptionsCreator
|
||||||
{
|
{
|
||||||
AuthenticationOptions Create(FileReRoute fileReRoute);
|
AuthenticationOptions Create(FileReRoute reRoute);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
using Ocelot.Configuration.File;
|
||||||
|
|
||||||
|
namespace Ocelot.Configuration.Creator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Describes creation of HttpHandlerOptions
|
||||||
|
/// </summary>
|
||||||
|
public interface IHttpHandlerOptionsCreator
|
||||||
|
{
|
||||||
|
HttpHandlerOptions Create(FileReRoute fileReRoute);
|
||||||
|
}
|
||||||
|
}
|
@ -36,7 +36,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
|
|
||||||
private bool IsAuthenticated(FileReRoute fileReRoute)
|
private bool IsAuthenticated(FileReRoute fileReRoute)
|
||||||
{
|
{
|
||||||
return !string.IsNullOrEmpty(fileReRoute.AuthenticationOptions?.Provider);
|
return !string.IsNullOrEmpty(fileReRoute.AuthenticationOptions?.AuthenticationProviderKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsAuthorised(FileReRoute fileReRoute)
|
private bool IsAuthorised(FileReRoute fileReRoute)
|
||||||
|
@ -41,8 +41,8 @@ namespace Ocelot.Configuration.Creator
|
|||||||
}
|
}
|
||||||
|
|
||||||
var route = reRoute.ReRouteIsCaseSensitive
|
var route = reRoute.ReRouteIsCaseSensitive
|
||||||
? $"{upstreamTemplate}{RegExMatchEndString}"
|
? $"^{upstreamTemplate}{RegExMatchEndString}"
|
||||||
: $"{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}";
|
: $"^{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}";
|
||||||
|
|
||||||
return route;
|
return route;
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,9 @@ namespace Ocelot.Configuration.File
|
|||||||
public FileAuthenticationOptions()
|
public FileAuthenticationOptions()
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>();
|
AllowedScopes = new List<string>();
|
||||||
IdentityServerConfig = new FileIdentityServerConfig();
|
|
||||||
JwtConfig = new FileJwtConfig();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Provider { get; set; }
|
public string AuthenticationProviderKey {get; set;}
|
||||||
public List<string> AllowedScopes { get; set; }
|
public List<string> AllowedScopes { get; set; }
|
||||||
public FileIdentityServerConfig IdentityServerConfig { get; set; }
|
|
||||||
public FileJwtConfig JwtConfig { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
src/Ocelot/Configuration/File/FileHttpHandlerOptions.cs
Normal file
15
src/Ocelot/Configuration/File/FileHttpHandlerOptions.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
namespace Ocelot.Configuration.File
|
||||||
|
{
|
||||||
|
public class FileHttpHandlerOptions
|
||||||
|
{
|
||||||
|
public FileHttpHandlerOptions()
|
||||||
|
{
|
||||||
|
AllowAutoRedirect = true;
|
||||||
|
UseCookieContainer = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AllowAutoRedirect { get; set; }
|
||||||
|
|
||||||
|
public bool UseCookieContainer { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -11,16 +11,16 @@ namespace Ocelot.Configuration.File
|
|||||||
AddClaimsToRequest = new Dictionary<string, string>();
|
AddClaimsToRequest = new Dictionary<string, string>();
|
||||||
RouteClaimsRequirement = new Dictionary<string, string>();
|
RouteClaimsRequirement = new Dictionary<string, string>();
|
||||||
AddQueriesToRequest = new Dictionary<string, string>();
|
AddQueriesToRequest = new Dictionary<string, string>();
|
||||||
AuthenticationOptions = new FileAuthenticationOptions();
|
|
||||||
FileCacheOptions = new FileCacheOptions();
|
FileCacheOptions = new FileCacheOptions();
|
||||||
QoSOptions = new FileQoSOptions();
|
QoSOptions = new FileQoSOptions();
|
||||||
RateLimitOptions = new FileRateLimitRule();
|
RateLimitOptions = new FileRateLimitRule();
|
||||||
|
AuthenticationOptions = new FileAuthenticationOptions();
|
||||||
|
HttpHandlerOptions = new FileHttpHandlerOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string DownstreamPathTemplate { get; set; }
|
public string DownstreamPathTemplate { get; set; }
|
||||||
public string UpstreamPathTemplate { get; set; }
|
public string UpstreamPathTemplate { get; set; }
|
||||||
public List<string> UpstreamHttpMethod { get; set; }
|
public List<string> UpstreamHttpMethod { get; set; }
|
||||||
public FileAuthenticationOptions AuthenticationOptions { get; set; }
|
|
||||||
public Dictionary<string, string> AddHeadersToRequest { get; set; }
|
public Dictionary<string, string> AddHeadersToRequest { get; set; }
|
||||||
public Dictionary<string, string> AddClaimsToRequest { get; set; }
|
public Dictionary<string, string> AddClaimsToRequest { get; set; }
|
||||||
public Dictionary<string, string> RouteClaimsRequirement { get; set; }
|
public Dictionary<string, string> RouteClaimsRequirement { get; set; }
|
||||||
@ -35,5 +35,7 @@ namespace Ocelot.Configuration.File
|
|||||||
public FileQoSOptions QoSOptions { get; set; }
|
public FileQoSOptions QoSOptions { get; set; }
|
||||||
public string LoadBalancer {get;set;}
|
public string LoadBalancer {get;set;}
|
||||||
public FileRateLimitRule RateLimitOptions { get; set; }
|
public FileRateLimitRule RateLimitOptions { get; set; }
|
||||||
|
public FileAuthenticationOptions AuthenticationOptions { get; set; }
|
||||||
|
public FileHttpHandlerOptions HttpHandlerOptions { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
25
src/Ocelot/Configuration/HttpHandlerOptions.cs
Normal file
25
src/Ocelot/Configuration/HttpHandlerOptions.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
namespace Ocelot.Configuration
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Describes configuration parameters for http handler,
|
||||||
|
/// that is created to handle a request to service
|
||||||
|
/// </summary>
|
||||||
|
public class HttpHandlerOptions
|
||||||
|
{
|
||||||
|
public HttpHandlerOptions(bool allowAutoRedirect, bool useCookieContainer)
|
||||||
|
{
|
||||||
|
AllowAutoRedirect = allowAutoRedirect;
|
||||||
|
UseCookieContainer = useCookieContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specify if auto redirect is enabled
|
||||||
|
/// </summary>
|
||||||
|
public bool AllowAutoRedirect { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specify is handler has to use a cookie container
|
||||||
|
/// </summary>
|
||||||
|
public bool UseCookieContainer { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
@ -29,7 +29,8 @@ namespace Ocelot.Configuration
|
|||||||
bool isQos,
|
bool isQos,
|
||||||
QoSOptions qosOptions,
|
QoSOptions qosOptions,
|
||||||
bool enableEndpointRateLimiting,
|
bool enableEndpointRateLimiting,
|
||||||
RateLimitOptions ratelimitOptions)
|
RateLimitOptions ratelimitOptions,
|
||||||
|
HttpHandlerOptions httpHandlerOptions)
|
||||||
{
|
{
|
||||||
ReRouteKey = reRouteKey;
|
ReRouteKey = reRouteKey;
|
||||||
ServiceProviderConfiguraion = serviceProviderConfiguraion;
|
ServiceProviderConfiguraion = serviceProviderConfiguraion;
|
||||||
@ -58,6 +59,7 @@ namespace Ocelot.Configuration
|
|||||||
QosOptionsOptions = qosOptions;
|
QosOptionsOptions = qosOptions;
|
||||||
EnableEndpointEndpointRateLimiting = enableEndpointRateLimiting;
|
EnableEndpointEndpointRateLimiting = enableEndpointRateLimiting;
|
||||||
RateLimitOptions = ratelimitOptions;
|
RateLimitOptions = ratelimitOptions;
|
||||||
|
HttpHandlerOptions = httpHandlerOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ReRouteKey {get;private set;}
|
public string ReRouteKey {get;private set;}
|
||||||
@ -84,5 +86,6 @@ namespace Ocelot.Configuration
|
|||||||
public ServiceProviderConfiguration ServiceProviderConfiguraion { get; private set; }
|
public ServiceProviderConfiguration ServiceProviderConfiguraion { get; private set; }
|
||||||
public bool EnableEndpointEndpointRateLimiting { get; private set; }
|
public bool EnableEndpointEndpointRateLimiting { get; private set; }
|
||||||
public RateLimitOptions RateLimitOptions { get; private set; }
|
public RateLimitOptions RateLimitOptions { get; private set; }
|
||||||
|
public HttpHandlerOptions HttpHandlerOptions { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,8 +3,6 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Consul;
|
using Consul;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Ocelot.Authentication.JsonConverters;
|
|
||||||
using Ocelot.Responses;
|
using Ocelot.Responses;
|
||||||
using Ocelot.ServiceDiscovery;
|
using Ocelot.ServiceDiscovery;
|
||||||
|
|
||||||
@ -49,9 +47,7 @@ namespace Ocelot.Configuration.Repository
|
|||||||
|
|
||||||
var json = Encoding.UTF8.GetString(bytes);
|
var json = Encoding.UTF8.GetString(bytes);
|
||||||
|
|
||||||
var settings = new JsonSerializerSettings();
|
var consulConfig = JsonConvert.DeserializeObject<OcelotConfiguration>(json);
|
||||||
settings.Converters.Add(new AuthenticationConfigConverter());
|
|
||||||
var consulConfig = JsonConvert.DeserializeObject<OcelotConfiguration>(json, settings);
|
|
||||||
|
|
||||||
return new OkResponse<IOcelotConfiguration>(consulConfig);
|
return new OkResponse<IOcelotConfiguration>(consulConfig);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
using Ocelot.Errors;
|
||||||
|
|
||||||
|
namespace Ocelot.Configuration.Validator
|
||||||
|
{
|
||||||
|
public class PathTemplateDoesntStartWithForwardSlash : Error
|
||||||
|
{
|
||||||
|
public PathTemplateDoesntStartWithForwardSlash(string message)
|
||||||
|
: base(message, OcelotErrorCode.PathTemplateDoesntStartWithForwardSlash)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Ocelot.Authentication.Handler;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Errors;
|
using Ocelot.Errors;
|
||||||
using Ocelot.Responses;
|
using Ocelot.Responses;
|
||||||
@ -10,7 +10,14 @@ namespace Ocelot.Configuration.Validator
|
|||||||
{
|
{
|
||||||
public class FileConfigurationValidator : IConfigurationValidator
|
public class FileConfigurationValidator : IConfigurationValidator
|
||||||
{
|
{
|
||||||
public Response<ConfigurationValidationResult> IsValid(FileConfiguration configuration)
|
private readonly IAuthenticationSchemeProvider _provider;
|
||||||
|
|
||||||
|
public FileConfigurationValidator(IAuthenticationSchemeProvider provider)
|
||||||
|
{
|
||||||
|
_provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Response<ConfigurationValidationResult>> IsValid(FileConfiguration configuration)
|
||||||
{
|
{
|
||||||
var result = CheckForDuplicateReRoutes(configuration);
|
var result = CheckForDuplicateReRoutes(configuration);
|
||||||
|
|
||||||
@ -19,7 +26,21 @@ namespace Ocelot.Configuration.Validator
|
|||||||
return new OkResponse<ConfigurationValidationResult>(result);
|
return new OkResponse<ConfigurationValidationResult>(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = CheckForUnsupportedAuthenticationProviders(configuration);
|
result = CheckDownstreamTemplatePathBeingsWithForwardSlash(configuration);
|
||||||
|
|
||||||
|
if (result.IsError)
|
||||||
|
{
|
||||||
|
return new OkResponse<ConfigurationValidationResult>(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = CheckUpstreamTemplatePathBeingsWithForwardSlash(configuration);
|
||||||
|
|
||||||
|
if (result.IsError)
|
||||||
|
{
|
||||||
|
return new OkResponse<ConfigurationValidationResult>(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = await CheckForUnsupportedAuthenticationProviders(configuration);
|
||||||
|
|
||||||
if (result.IsError)
|
if (result.IsError)
|
||||||
{
|
{
|
||||||
@ -42,25 +63,67 @@ namespace Ocelot.Configuration.Validator
|
|||||||
return new OkResponse<ConfigurationValidationResult>(result);
|
return new OkResponse<ConfigurationValidationResult>(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConfigurationValidationResult CheckForUnsupportedAuthenticationProviders(FileConfiguration configuration)
|
private ConfigurationValidationResult CheckDownstreamTemplatePathBeingsWithForwardSlash(FileConfiguration configuration)
|
||||||
{
|
{
|
||||||
var errors = new List<Error>();
|
var errors = new List<Error>();
|
||||||
|
|
||||||
foreach(var reRoute in configuration.ReRoutes)
|
foreach(var reRoute in configuration.ReRoutes)
|
||||||
{
|
{
|
||||||
var isAuthenticated = !string.IsNullOrEmpty(reRoute.AuthenticationOptions?.Provider);
|
if(!reRoute.DownstreamPathTemplate.StartsWith("/"))
|
||||||
|
{
|
||||||
|
errors.Add(new PathTemplateDoesntStartWithForwardSlash($"{reRoute.DownstreamPathTemplate} doesnt start with forward slash"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(errors.Any())
|
||||||
|
{
|
||||||
|
return new ConfigurationValidationResult(true, errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ConfigurationValidationResult(false, errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfigurationValidationResult CheckUpstreamTemplatePathBeingsWithForwardSlash(FileConfiguration configuration)
|
||||||
|
{
|
||||||
|
var errors = new List<Error>();
|
||||||
|
|
||||||
|
foreach(var reRoute in configuration.ReRoutes)
|
||||||
|
{
|
||||||
|
if(!reRoute.UpstreamPathTemplate.StartsWith("/"))
|
||||||
|
{
|
||||||
|
errors.Add(new PathTemplateDoesntStartWithForwardSlash($"{reRoute.DownstreamPathTemplate} doesnt start with forward slash"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(errors.Any())
|
||||||
|
{
|
||||||
|
return new ConfigurationValidationResult(true, errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ConfigurationValidationResult(false, errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<ConfigurationValidationResult> CheckForUnsupportedAuthenticationProviders(FileConfiguration configuration)
|
||||||
|
{
|
||||||
|
var errors = new List<Error>();
|
||||||
|
|
||||||
|
foreach (var reRoute in configuration.ReRoutes)
|
||||||
|
{
|
||||||
|
var isAuthenticated = !string.IsNullOrEmpty(reRoute.AuthenticationOptions.AuthenticationProviderKey);
|
||||||
|
|
||||||
if (!isAuthenticated)
|
if (!isAuthenticated)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsSupportedAuthenticationProvider(reRoute.AuthenticationOptions?.Provider))
|
var data = await _provider.GetAllSchemesAsync();
|
||||||
|
var schemes = data.ToList();
|
||||||
|
if (schemes.Any(x => x.Name == reRoute.AuthenticationOptions.AuthenticationProviderKey))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var error = new UnsupportedAuthenticationProviderError($"{reRoute.AuthenticationOptions?.Provider} is unsupported authentication provider, upstream template is {reRoute.UpstreamPathTemplate}, upstream method is {reRoute.UpstreamHttpMethod}");
|
var error = new UnsupportedAuthenticationProviderError($"{reRoute.AuthenticationOptions.AuthenticationProviderKey} is unsupported authentication provider, upstream template is {reRoute.UpstreamPathTemplate}, upstream method is {reRoute.UpstreamHttpMethod}");
|
||||||
errors.Add(error);
|
errors.Add(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,13 +132,6 @@ namespace Ocelot.Configuration.Validator
|
|||||||
: new ConfigurationValidationResult(false);
|
: new ConfigurationValidationResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsSupportedAuthenticationProvider(string provider)
|
|
||||||
{
|
|
||||||
SupportedAuthenticationProviders supportedProvider;
|
|
||||||
|
|
||||||
return Enum.TryParse(provider, true, out supportedProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ConfigurationValidationResult CheckForReRoutesContainingDownstreamSchemeInDownstreamPathTemplate(FileConfiguration configuration)
|
private ConfigurationValidationResult CheckForReRoutesContainingDownstreamSchemeInDownstreamPathTemplate(FileConfiguration configuration)
|
||||||
{
|
{
|
||||||
var errors = new List<Error>();
|
var errors = new List<Error>();
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
using Ocelot.Configuration.File;
|
using System.Threading.Tasks;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Responses;
|
using Ocelot.Responses;
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Validator
|
namespace Ocelot.Configuration.Validator
|
||||||
{
|
{
|
||||||
public interface IConfigurationValidator
|
public interface IConfigurationValidator
|
||||||
{
|
{
|
||||||
Response<ConfigurationValidationResult> IsValid(FileConfiguration configuration);
|
Task<Response<ConfigurationValidationResult>> IsValid(FileConfiguration configuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
using Ocelot.Configuration;
|
|
||||||
using Ocelot.Configuration.File;
|
|
||||||
|
|
||||||
namespace Ocelot.Creator.Configuration
|
|
||||||
{
|
|
||||||
public interface IAuthenticationProviderConfigCreator
|
|
||||||
{
|
|
||||||
IAuthenticationConfig Create(FileAuthenticationOptions authenticationOptions);
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,8 +4,6 @@ using Microsoft.AspNetCore.Http;
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
using Ocelot.Authentication.Handler.Creator;
|
|
||||||
using Ocelot.Authentication.Handler.Factory;
|
|
||||||
using Ocelot.Authorisation;
|
using Ocelot.Authorisation;
|
||||||
using Ocelot.Cache;
|
using Ocelot.Cache;
|
||||||
using Ocelot.Claims;
|
using Ocelot.Claims;
|
||||||
@ -38,13 +36,15 @@ using Ocelot.Responder;
|
|||||||
using Ocelot.ServiceDiscovery;
|
using Ocelot.ServiceDiscovery;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using IdentityServer4.AccessTokenValidation;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
using Ocelot.Creator.Configuration;
|
|
||||||
using FileConfigurationProvider = Ocelot.Configuration.Provider.FileConfigurationProvider;
|
using FileConfigurationProvider = Ocelot.Configuration.Provider.FileConfigurationProvider;
|
||||||
|
|
||||||
namespace Ocelot.DependencyInjection
|
namespace Ocelot.DependencyInjection
|
||||||
@ -72,10 +72,8 @@ namespace Ocelot.DependencyInjection
|
|||||||
|
|
||||||
services.Configure<FileConfiguration>(configurationRoot);
|
services.Configure<FileConfiguration>(configurationRoot);
|
||||||
services.TryAddSingleton<IOcelotConfigurationCreator, FileOcelotConfigurationCreator>();
|
services.TryAddSingleton<IOcelotConfigurationCreator, FileOcelotConfigurationCreator>();
|
||||||
services.TryAddSingleton<IAuthenticationProviderConfigCreator, AuthenticationProviderConfigCreator>();
|
|
||||||
services.TryAddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>();
|
services.TryAddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>();
|
||||||
services.TryAddSingleton<IConfigurationValidator, FileConfigurationValidator>();
|
services.TryAddSingleton<IConfigurationValidator, FileConfigurationValidator>();
|
||||||
services.TryAddSingleton<IBaseUrlFinder, BaseUrlFinder>();
|
|
||||||
services.TryAddSingleton<IClaimsToThingCreator, ClaimsToThingCreator>();
|
services.TryAddSingleton<IClaimsToThingCreator, ClaimsToThingCreator>();
|
||||||
services.TryAddSingleton<IAuthenticationOptionsCreator, AuthenticationOptionsCreator>();
|
services.TryAddSingleton<IAuthenticationOptionsCreator, AuthenticationOptionsCreator>();
|
||||||
services.TryAddSingleton<IUpstreamTemplatePatternCreator, UpstreamTemplatePatternCreator>();
|
services.TryAddSingleton<IUpstreamTemplatePatternCreator, UpstreamTemplatePatternCreator>();
|
||||||
@ -84,59 +82,7 @@ namespace Ocelot.DependencyInjection
|
|||||||
services.TryAddSingleton<IQoSOptionsCreator, QoSOptionsCreator>();
|
services.TryAddSingleton<IQoSOptionsCreator, QoSOptionsCreator>();
|
||||||
services.TryAddSingleton<IReRouteOptionsCreator, ReRouteOptionsCreator>();
|
services.TryAddSingleton<IReRouteOptionsCreator, ReRouteOptionsCreator>();
|
||||||
services.TryAddSingleton<IRateLimitOptionsCreator, RateLimitOptionsCreator>();
|
services.TryAddSingleton<IRateLimitOptionsCreator, RateLimitOptionsCreator>();
|
||||||
|
services.TryAddSingleton<IBaseUrlFinder, BaseUrlFinder>();
|
||||||
var identityServerConfiguration = IdentityServerConfigurationCreator.GetIdentityServerConfiguration();
|
|
||||||
|
|
||||||
if(identityServerConfiguration != null)
|
|
||||||
{
|
|
||||||
services.TryAddSingleton<IIdentityServerConfiguration>(identityServerConfiguration);
|
|
||||||
services.TryAddSingleton<IHashMatcher, HashMatcher>();
|
|
||||||
var identityServerBuilder = services
|
|
||||||
.AddIdentityServer(options => {
|
|
||||||
options.IssuerUri = "Ocelot";
|
|
||||||
})
|
|
||||||
.AddInMemoryApiResources(new List<ApiResource>
|
|
||||||
{
|
|
||||||
new ApiResource
|
|
||||||
{
|
|
||||||
Name = identityServerConfiguration.ApiName,
|
|
||||||
Description = identityServerConfiguration.Description,
|
|
||||||
Enabled = identityServerConfiguration.Enabled,
|
|
||||||
DisplayName = identityServerConfiguration.ApiName,
|
|
||||||
Scopes = identityServerConfiguration.AllowedScopes.Select(x => new Scope(x)).ToList(),
|
|
||||||
ApiSecrets = new List<Secret>
|
|
||||||
{
|
|
||||||
new Secret
|
|
||||||
{
|
|
||||||
Value = identityServerConfiguration.ApiSecret.Sha256()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.AddInMemoryClients(new List<Client>
|
|
||||||
{
|
|
||||||
new Client
|
|
||||||
{
|
|
||||||
ClientId = identityServerConfiguration.ApiName,
|
|
||||||
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
|
|
||||||
ClientSecrets = new List<Secret> {new Secret(identityServerConfiguration.ApiSecret.Sha256())},
|
|
||||||
AllowedScopes = identityServerConfiguration.AllowedScopes,
|
|
||||||
AccessTokenType = identityServerConfiguration.AccessTokenType,
|
|
||||||
Enabled = identityServerConfiguration.Enabled,
|
|
||||||
RequireClientSecret = identityServerConfiguration.RequireClientSecret
|
|
||||||
}
|
|
||||||
}).AddResourceOwnerValidator<OcelotResourceOwnerPasswordValidator>();
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(identityServerConfiguration.CredentialsSigningCertificateLocation) || string.IsNullOrEmpty(identityServerConfiguration.CredentialsSigningCertificatePassword))
|
|
||||||
{
|
|
||||||
identityServerBuilder.AddTemporarySigningCredential();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var cert = new X509Certificate2(identityServerConfiguration.CredentialsSigningCertificateLocation, identityServerConfiguration.CredentialsSigningCertificatePassword);
|
|
||||||
identityServerBuilder.AddSigningCredential(cert);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var assembly = typeof(FileConfigurationController).GetTypeInfo().Assembly;
|
var assembly = typeof(FileConfigurationController).GetTypeInfo().Assembly;
|
||||||
|
|
||||||
@ -175,11 +121,10 @@ namespace Ocelot.DependencyInjection
|
|||||||
services.TryAddSingleton<IHttpResponder, HttpContextResponder>();
|
services.TryAddSingleton<IHttpResponder, HttpContextResponder>();
|
||||||
services.TryAddSingleton<IRequestCreator, HttpRequestCreator>();
|
services.TryAddSingleton<IRequestCreator, HttpRequestCreator>();
|
||||||
services.TryAddSingleton<IErrorsToHttpStatusCodeMapper, ErrorsToHttpStatusCodeMapper>();
|
services.TryAddSingleton<IErrorsToHttpStatusCodeMapper, ErrorsToHttpStatusCodeMapper>();
|
||||||
services.TryAddSingleton<IAuthenticationHandlerFactory, AuthenticationHandlerFactory>();
|
|
||||||
services.TryAddSingleton<IAuthenticationHandlerCreator, AuthenticationHandlerCreator>();
|
|
||||||
services.TryAddSingleton<IRateLimitCounterHandler, MemoryCacheRateLimitCounterHandler>();
|
services.TryAddSingleton<IRateLimitCounterHandler, MemoryCacheRateLimitCounterHandler>();
|
||||||
services.TryAddSingleton<IHttpClientCache, MemoryHttpClientCache>();
|
services.TryAddSingleton<IHttpClientCache, MemoryHttpClientCache>();
|
||||||
services.TryAddSingleton<IRequestMapper, RequestMapper>();
|
services.TryAddSingleton<IRequestMapper, RequestMapper>();
|
||||||
|
services.TryAddSingleton<IHttpHandlerOptionsCreator, HttpHandlerOptionsCreator>();
|
||||||
|
|
||||||
// see this for why we register this as singleton http://stackoverflow.com/questions/37371264/invalidoperationexception-unable-to-resolve-service-for-type-microsoft-aspnetc
|
// see this for why we register this as singleton http://stackoverflow.com/questions/37371264/invalidoperationexception-unable-to-resolve-service-for-type-microsoft-aspnetc
|
||||||
// could maybe use a scoped data repository
|
// could maybe use a scoped data repository
|
||||||
@ -190,8 +135,89 @@ namespace Ocelot.DependencyInjection
|
|||||||
//Used to log the the start and ending of middleware
|
//Used to log the the start and ending of middleware
|
||||||
services.TryAddSingleton<OcelotDiagnosticListener>();
|
services.TryAddSingleton<OcelotDiagnosticListener>();
|
||||||
services.AddMiddlewareAnalysis();
|
services.AddMiddlewareAnalysis();
|
||||||
|
services.AddWebEncoders();
|
||||||
|
|
||||||
|
var identityServerConfiguration = IdentityServerConfigurationCreator.GetIdentityServerConfiguration();
|
||||||
|
|
||||||
|
if (identityServerConfiguration != null)
|
||||||
|
{
|
||||||
|
services.AddIdentityServer(identityServerConfiguration, configurationRoot);
|
||||||
|
}
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void AddIdentityServer(this IServiceCollection services, IIdentityServerConfiguration identityServerConfiguration, IConfigurationRoot configurationRoot)
|
||||||
|
{
|
||||||
|
services.TryAddSingleton<IIdentityServerConfiguration>(identityServerConfiguration);
|
||||||
|
services.TryAddSingleton<IHashMatcher, HashMatcher>();
|
||||||
|
var identityServerBuilder = services
|
||||||
|
.AddIdentityServer(o => {
|
||||||
|
o.IssuerUri = "Ocelot";
|
||||||
|
})
|
||||||
|
.AddInMemoryApiResources(Resources(identityServerConfiguration))
|
||||||
|
.AddInMemoryClients(Client(identityServerConfiguration))
|
||||||
|
.AddResourceOwnerValidator<OcelotResourceOwnerPasswordValidator>();
|
||||||
|
|
||||||
|
//todo - refactor a method so we know why this is happening
|
||||||
|
var whb = services.First(x => x.ServiceType == typeof(IWebHostBuilder));
|
||||||
|
var urlFinder = new BaseUrlFinder((IWebHostBuilder)whb.ImplementationInstance);
|
||||||
|
var baseSchemeUrlAndPort = urlFinder.Find();
|
||||||
|
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
|
||||||
|
|
||||||
|
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
|
||||||
|
.AddIdentityServerAuthentication(o =>
|
||||||
|
{
|
||||||
|
var adminPath = configurationRoot.GetValue("GlobalConfiguration:AdministrationPath", string.Empty);
|
||||||
|
o.Authority = baseSchemeUrlAndPort + adminPath;
|
||||||
|
o.ApiName = identityServerConfiguration.ApiName;
|
||||||
|
o.RequireHttpsMetadata = identityServerConfiguration.RequireHttps;
|
||||||
|
o.SupportedTokens = SupportedTokens.Both;
|
||||||
|
o.ApiSecret = identityServerConfiguration.ApiSecret;
|
||||||
|
});
|
||||||
|
|
||||||
|
//todo - refactor naming..
|
||||||
|
if (string.IsNullOrEmpty(identityServerConfiguration.CredentialsSigningCertificateLocation) || string.IsNullOrEmpty(identityServerConfiguration.CredentialsSigningCertificatePassword))
|
||||||
|
{
|
||||||
|
identityServerBuilder.AddDeveloperSigningCredential();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//todo - refactor so calls method?
|
||||||
|
var cert = new X509Certificate2(identityServerConfiguration.CredentialsSigningCertificateLocation, identityServerConfiguration.CredentialsSigningCertificatePassword);
|
||||||
|
identityServerBuilder.AddSigningCredential(cert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<ApiResource> Resources(IIdentityServerConfiguration identityServerConfiguration)
|
||||||
|
{
|
||||||
|
return new List<ApiResource>
|
||||||
|
{
|
||||||
|
new ApiResource(identityServerConfiguration.ApiName, identityServerConfiguration.ApiName)
|
||||||
|
{
|
||||||
|
ApiSecrets = new List<Secret>
|
||||||
|
{
|
||||||
|
new Secret
|
||||||
|
{
|
||||||
|
Value = identityServerConfiguration.ApiSecret.Sha256()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Client> Client(IIdentityServerConfiguration identityServerConfiguration)
|
||||||
|
{
|
||||||
|
return new List<Client>
|
||||||
|
{
|
||||||
|
new Client
|
||||||
|
{
|
||||||
|
ClientId = identityServerConfiguration.ApiName,
|
||||||
|
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
|
||||||
|
ClientSecrets = new List<Secret> {new Secret(identityServerConfiguration.ApiSecret.Sha256())},
|
||||||
|
AllowedScopes = { identityServerConfiguration.ApiName }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ using Ocelot.Configuration.Provider;
|
|||||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||||
using Ocelot.Errors;
|
using Ocelot.Errors;
|
||||||
using Ocelot.Responses;
|
using Ocelot.Responses;
|
||||||
|
using Ocelot.Utilities;
|
||||||
|
|
||||||
namespace Ocelot.DownstreamRouteFinder.Finder
|
namespace Ocelot.DownstreamRouteFinder.Finder
|
||||||
{
|
{
|
||||||
@ -24,6 +25,8 @@ namespace Ocelot.DownstreamRouteFinder.Finder
|
|||||||
|
|
||||||
public async Task<Response<DownstreamRoute>> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod)
|
public async Task<Response<DownstreamRoute>> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod)
|
||||||
{
|
{
|
||||||
|
upstreamUrlPath = upstreamUrlPath.SetLastCharacterAs('/');
|
||||||
|
|
||||||
var configuration = await _configProvider.Get();
|
var configuration = await _configProvider.Get();
|
||||||
|
|
||||||
var applicableReRoutes = configuration.Data.ReRoutes.Where(r => r.UpstreamHttpMethod.Count == 0 || r.UpstreamHttpMethod.Select(x => x.Method.ToLower()).Contains(upstreamHttpMethod.ToLower()));
|
var applicableReRoutes = configuration.Data.ReRoutes.Where(r => r.UpstreamHttpMethod.Count == 0 || r.UpstreamHttpMethod.Select(x => x.Method.ToLower()).Contains(upstreamHttpMethod.ToLower()));
|
||||||
|
@ -30,7 +30,7 @@ namespace Ocelot.DownstreamRouteFinder.Middleware
|
|||||||
|
|
||||||
public async Task Invoke(HttpContext context)
|
public async Task Invoke(HttpContext context)
|
||||||
{
|
{
|
||||||
var upstreamUrlPath = context.Request.Path.ToString().SetLastCharacterAs('/');
|
var upstreamUrlPath = context.Request.Path.ToString();
|
||||||
|
|
||||||
_logger.LogDebug("upstream url path is {upstreamUrlPath}", upstreamUrlPath);
|
_logger.LogDebug("upstream url path is {upstreamUrlPath}", upstreamUrlPath);
|
||||||
|
|
||||||
|
@ -49,12 +49,8 @@ namespace Ocelot.Errors.Middleware
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void SetInternalServerErrorOnResponse(HttpContext context)
|
private void SetInternalServerErrorOnResponse(HttpContext context)
|
||||||
{
|
|
||||||
context.Response.OnStarting(x =>
|
|
||||||
{
|
{
|
||||||
context.Response.StatusCode = 500;
|
context.Response.StatusCode = 500;
|
||||||
return Task.CompletedTask;
|
|
||||||
}, context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string CreateMessage(HttpContext context, Exception e)
|
private string CreateMessage(HttpContext context, Exception e)
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
UnableToFindQoSProviderError,
|
UnableToFindQoSProviderError,
|
||||||
UnableToSetConfigInConsulError,
|
UnableToSetConfigInConsulError,
|
||||||
UnmappableRequestError,
|
UnmappableRequestError,
|
||||||
RateLimitOptionsError
|
RateLimitOptionsError,
|
||||||
|
PathTemplateDoesntStartWithForwardSlash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Reflection;
|
||||||
using IdentityServer4.AccessTokenValidation;
|
using IdentityServer4.AccessTokenValidation;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Ocelot.Authentication.Middleware;
|
using Ocelot.Authentication.Middleware;
|
||||||
using Ocelot.Cache.Middleware;
|
using Ocelot.Cache.Middleware;
|
||||||
using Ocelot.Claims.Middleware;
|
using Ocelot.Claims.Middleware;
|
||||||
|
using Ocelot.Controllers;
|
||||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||||
using Ocelot.DownstreamUrlCreator.Middleware;
|
using Ocelot.DownstreamUrlCreator.Middleware;
|
||||||
using Ocelot.Errors.Middleware;
|
using Ocelot.Errors.Middleware;
|
||||||
@ -178,25 +181,10 @@ namespace Ocelot.Middleware
|
|||||||
|
|
||||||
if(!string.IsNullOrEmpty(configuration.AdministrationPath) && identityServerConfiguration != null)
|
if(!string.IsNullOrEmpty(configuration.AdministrationPath) && identityServerConfiguration != null)
|
||||||
{
|
{
|
||||||
var urlFinder = (IBaseUrlFinder)builder.ApplicationServices.GetService(typeof(IBaseUrlFinder));
|
|
||||||
|
|
||||||
var baseSchemeUrlAndPort = urlFinder.Find();
|
|
||||||
|
|
||||||
builder.Map(configuration.AdministrationPath, app =>
|
builder.Map(configuration.AdministrationPath, app =>
|
||||||
{
|
{
|
||||||
var identityServerUrl = $"{baseSchemeUrlAndPort}/{configuration.AdministrationPath.Remove(0,1)}";
|
|
||||||
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
|
|
||||||
{
|
|
||||||
Authority = identityServerUrl,
|
|
||||||
ApiName = identityServerConfiguration.ApiName,
|
|
||||||
RequireHttpsMetadata = identityServerConfiguration.RequireHttps,
|
|
||||||
AllowedScopes = identityServerConfiguration.AllowedScopes,
|
|
||||||
SupportedTokens = SupportedTokens.Both,
|
|
||||||
ApiSecret = identityServerConfiguration.ApiSecret
|
|
||||||
});
|
|
||||||
|
|
||||||
app.UseIdentityServer();
|
app.UseIdentityServer();
|
||||||
|
app.UseAuthentication();
|
||||||
app.UseMvc();
|
app.UseMvc();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
|
||||||
|
<NETStandardImplicitPackageVersion>2.0.0</NETStandardImplicitPackageVersion>
|
||||||
<Description>This project is aimed at people using .NET running a micro services / service orientated architecture that need a unified point of entry into their system. In particular I want easy integration with IdentityServer reference and bearer tokens. We have been unable to find this in my current workplace without having to write our own Javascript middlewares to handle the IdentityServer reference tokens. We would rather use the IdentityServer code that already exists to do this. Ocelot is a bunch of middlewares in a specific order. Ocelot manipulates the HttpRequest object into a state specified by its configuration until it reaches a request builder middleware where it creates a HttpRequestMessage object which is used to make a request to a downstream service. The middleware that makes the request is the last thing in the Ocelot pipeline. It does not call the next middleware. The response from the downstream service is stored in a per request scoped repository and retrived as the requests goes back up the Ocelot pipeline. There is a piece of middleware that maps the HttpResponseMessage onto the HttpResponse object and that is returned to the client. That is basically it with a bunch of other features.</Description>
|
<Description>This project is aimed at people using .NET running a micro services / service orientated architecture that need a unified point of entry into their system. In particular I want easy integration with IdentityServer reference and bearer tokens. We have been unable to find this in my current workplace without having to write our own Javascript middlewares to handle the IdentityServer reference tokens. We would rather use the IdentityServer code that already exists to do this. Ocelot is a bunch of middlewares in a specific order. Ocelot manipulates the HttpRequest object into a state specified by its configuration until it reaches a request builder middleware where it creates a HttpRequestMessage object which is used to make a request to a downstream service. The middleware that makes the request is the last thing in the Ocelot pipeline. It does not call the next middleware. The response from the downstream service is stored in a per request scoped repository and retrived as the requests goes back up the Ocelot pipeline. There is a piece of middleware that maps the HttpResponseMessage onto the HttpResponse object and that is returned to the client. That is basically it with a bunch of other features.</Description>
|
||||||
<AssemblyTitle>Ocelot</AssemblyTitle>
|
<AssemblyTitle>Ocelot</AssemblyTitle>
|
||||||
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
|
||||||
<NetStandardImplicitPackageVersion>1.6.1</NetStandardImplicitPackageVersion>
|
|
||||||
<AssemblyName>Ocelot</AssemblyName>
|
<AssemblyName>Ocelot</AssemblyName>
|
||||||
<PackageId>Ocelot</PackageId>
|
<PackageId>Ocelot</PackageId>
|
||||||
<PackageTags>API Gateway;.NET core</PackageTags>
|
<PackageTags>API Gateway;.NET core</PackageTags>
|
||||||
<PackageProjectUrl>https://github.com/TomPallister/Ocelot</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/TomPallister/Ocelot</PackageProjectUrl>
|
||||||
<PackageProjectUrl>https://github.com/TomPallister/Ocelot</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/TomPallister/Ocelot</PackageProjectUrl>
|
||||||
<RuntimeIdentifiers>win10-x64;osx.10.11-x64;osx.10.12-x64;win7-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win10-x64;osx.10.11-x64;osx.10.12-x64;win7-x64</RuntimeIdentifiers>
|
||||||
<RuntimeFrameworkVersion>1.1.1</RuntimeFrameworkVersion>
|
|
||||||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
||||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
@ -26,37 +26,23 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.MiddlewareAnalysis" Version="1.1.1" />
|
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.1.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DiagnosticAdapter" Version="1.1.0" />
|
<PackageReference Include="Microsoft.Extensions.DiagnosticAdapter" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="1.1.1" />
|
|
||||||
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.0" />
|
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OAuth" Version="1.1.1" />
|
<PackageReference Include="CacheManager.Core" Version="1.1.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="1.1.1" />
|
<PackageReference Include="CacheManager.Microsoft.Extensions.Configuration" Version="1.1.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="1.1.1" />
|
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="1.1.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="1.1.1" />
|
<PackageReference Include="Consul" Version="0.7.2.3" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="1.1.1" />
|
<PackageReference Include="Polly" Version="5.3.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Facebook" Version="1.1.1" />
|
<PackageReference Include="IdentityServer4" Version="2.0.2" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Twitter" Version="1.1.1" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="1.1.1" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="1.1.1" />
|
|
||||||
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="1.2.0" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.1.1" />
|
|
||||||
<PackageReference Include="CacheManager.Core" Version="0.9.2" />
|
|
||||||
<PackageReference Include="CacheManager.Microsoft.Extensions.Configuration" Version="0.9.2" />
|
|
||||||
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="0.9.2" />
|
|
||||||
<PackageReference Include="Consul" Version="0.7.2.1" />
|
|
||||||
<PackageReference Include="Polly" Version="5.0.3" />
|
|
||||||
<PackageReference Include="IdentityServer4" Version="1.5.1" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="1.1.1" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -10,9 +10,11 @@ namespace Ocelot.Request.Builder
|
|||||||
public async Task<Response<Request>> Build(
|
public async Task<Response<Request>> Build(
|
||||||
HttpRequestMessage httpRequestMessage,
|
HttpRequestMessage httpRequestMessage,
|
||||||
bool isQos,
|
bool isQos,
|
||||||
IQoSProvider qosProvider)
|
IQoSProvider qosProvider,
|
||||||
|
bool useCookieContainer,
|
||||||
|
bool allowAutoRedirect)
|
||||||
{
|
{
|
||||||
return new OkResponse<Request>(new Request(httpRequestMessage, isQos, qosProvider));
|
return new OkResponse<Request>(new Request(httpRequestMessage, isQos, qosProvider, useCookieContainer, allowAutoRedirect));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,6 +11,8 @@
|
|||||||
Task<Response<Request>> Build(
|
Task<Response<Request>> Build(
|
||||||
HttpRequestMessage httpRequestMessage,
|
HttpRequestMessage httpRequestMessage,
|
||||||
bool isQos,
|
bool isQos,
|
||||||
IQoSProvider qosProvider);
|
IQoSProvider qosProvider,
|
||||||
|
bool useCookieContainer,
|
||||||
|
bool allowAutoRedirect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,9 @@ namespace Ocelot.Request.Middleware
|
|||||||
var buildResult = await _requestCreator.Build(
|
var buildResult = await _requestCreator.Build(
|
||||||
DownstreamRequest,
|
DownstreamRequest,
|
||||||
DownstreamRoute.ReRoute.IsQos,
|
DownstreamRoute.ReRoute.IsQos,
|
||||||
qosProvider.Data);
|
qosProvider.Data,
|
||||||
|
DownstreamRoute.ReRoute.HttpHandlerOptions.UseCookieContainer,
|
||||||
|
DownstreamRoute.ReRoute.HttpHandlerOptions.AllowAutoRedirect);
|
||||||
|
|
||||||
if (buildResult.IsError)
|
if (buildResult.IsError)
|
||||||
{
|
{
|
||||||
|
@ -8,15 +8,21 @@ namespace Ocelot.Request
|
|||||||
public Request(
|
public Request(
|
||||||
HttpRequestMessage httpRequestMessage,
|
HttpRequestMessage httpRequestMessage,
|
||||||
bool isQos,
|
bool isQos,
|
||||||
IQoSProvider qosProvider)
|
IQoSProvider qosProvider,
|
||||||
|
bool allowAutoRedirect,
|
||||||
|
bool useCookieContainer)
|
||||||
{
|
{
|
||||||
HttpRequestMessage = httpRequestMessage;
|
HttpRequestMessage = httpRequestMessage;
|
||||||
IsQos = isQos;
|
IsQos = isQos;
|
||||||
QosProvider = qosProvider;
|
QosProvider = qosProvider;
|
||||||
|
AllowAutoRedirect = allowAutoRedirect;
|
||||||
|
UseCookieContainer = useCookieContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpRequestMessage HttpRequestMessage { get; private set; }
|
public HttpRequestMessage HttpRequestMessage { get; private set; }
|
||||||
public bool IsQos { get; private set; }
|
public bool IsQos { get; private set; }
|
||||||
public IQoSProvider QosProvider { get; private set; }
|
public IQoSProvider QosProvider { get; private set; }
|
||||||
|
public bool AllowAutoRedirect { get; private set; }
|
||||||
|
public bool UseCookieContainer { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,9 @@ namespace Ocelot.Requester
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IHttpClient Create()
|
public IHttpClient Create(bool useCookies, bool allowAutoRedirect)
|
||||||
{
|
{
|
||||||
var httpclientHandler = new HttpClientHandler();
|
var httpclientHandler = new HttpClientHandler { AllowAutoRedirect = allowAutoRedirect, UseCookies = useCookies};
|
||||||
|
|
||||||
var client = new HttpClient(CreateHttpMessageHandler(httpclientHandler));
|
var client = new HttpClient(CreateHttpMessageHandler(httpclientHandler));
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Ocelot.Configuration;
|
||||||
using Ocelot.Logging;
|
using Ocelot.Logging;
|
||||||
using Ocelot.Responses;
|
using Ocelot.Responses;
|
||||||
using Polly.CircuitBreaker;
|
using Polly.CircuitBreaker;
|
||||||
@ -14,7 +15,8 @@ namespace Ocelot.Requester
|
|||||||
private readonly IHttpClientCache _cacheHandlers;
|
private readonly IHttpClientCache _cacheHandlers;
|
||||||
private readonly IOcelotLogger _logger;
|
private readonly IOcelotLogger _logger;
|
||||||
|
|
||||||
public HttpClientHttpRequester(IOcelotLoggerFactory loggerFactory, IHttpClientCache cacheHandlers)
|
public HttpClientHttpRequester(IOcelotLoggerFactory loggerFactory,
|
||||||
|
IHttpClientCache cacheHandlers)
|
||||||
{
|
{
|
||||||
_logger = loggerFactory.CreateLogger<HttpClientHttpRequester>();
|
_logger = loggerFactory.CreateLogger<HttpClientHttpRequester>();
|
||||||
_cacheHandlers = cacheHandlers;
|
_cacheHandlers = cacheHandlers;
|
||||||
@ -26,7 +28,7 @@ namespace Ocelot.Requester
|
|||||||
|
|
||||||
var cacheKey = GetCacheKey(request, builder);
|
var cacheKey = GetCacheKey(request, builder);
|
||||||
|
|
||||||
var httpClient = GetHttpClient(cacheKey, builder);
|
var httpClient = GetHttpClient(cacheKey, builder, request.UseCookieContainer, request.AllowAutoRedirect);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -54,13 +56,13 @@ namespace Ocelot.Requester
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private IHttpClient GetHttpClient(string cacheKey, IHttpClientBuilder builder)
|
private IHttpClient GetHttpClient(string cacheKey, IHttpClientBuilder builder, bool useCookieContainer, bool allowAutoRedirect)
|
||||||
{
|
{
|
||||||
var httpClient = _cacheHandlers.Get(cacheKey);
|
var httpClient = _cacheHandlers.Get(cacheKey);
|
||||||
|
|
||||||
if (httpClient == null)
|
if (httpClient == null)
|
||||||
{
|
{
|
||||||
httpClient = builder.Create();
|
httpClient = builder.Create(useCookieContainer, allowAutoRedirect);
|
||||||
}
|
}
|
||||||
return httpClient;
|
return httpClient;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@ namespace Ocelot.Requester
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates the <see cref="HttpClient"/>
|
/// Creates the <see cref="HttpClient"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IHttpClient Create();
|
/// <param name="useCookies">Defines if http client should use cookie container</param>
|
||||||
|
/// <param name="allowAutoRedirect">Defines if http client should allow auto redirect</param>
|
||||||
|
IHttpClient Create(bool useCookies, bool allowAutoRedirect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using IdentityServer4.AccessTokenValidation;
|
||||||
using IdentityServer4.Models;
|
using IdentityServer4.Models;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
@ -14,7 +15,6 @@ using Xunit;
|
|||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
namespace Ocelot.AcceptanceTests
|
||||||
{
|
{
|
||||||
using IdentityServer4;
|
|
||||||
using IdentityServer4.Test;
|
using IdentityServer4.Test;
|
||||||
|
|
||||||
public class AuthenticationTests : IDisposable
|
public class AuthenticationTests : IDisposable
|
||||||
@ -28,10 +28,19 @@ namespace Ocelot.AcceptanceTests
|
|||||||
private int _downstreamServicePort = 51876;
|
private int _downstreamServicePort = 51876;
|
||||||
private string _downstreamServiceScheme = "http";
|
private string _downstreamServiceScheme = "http";
|
||||||
private string _downstreamServiceUrl = "http://localhost:51876";
|
private string _downstreamServiceUrl = "http://localhost:51876";
|
||||||
|
private readonly Action<IdentityServerAuthenticationOptions> _options;
|
||||||
|
|
||||||
public AuthenticationTests()
|
public AuthenticationTests()
|
||||||
{
|
{
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
|
_options = o =>
|
||||||
|
{
|
||||||
|
o.Authority = _identityServerRootUrl;
|
||||||
|
o.ApiName = "api";
|
||||||
|
o.RequireHttpsMetadata = false;
|
||||||
|
o.SupportedTokens = SupportedTokens.Both;
|
||||||
|
o.ApiSecret = "secret";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -51,14 +60,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
UpstreamHttpMethod = new List<string> { "Post" },
|
UpstreamHttpMethod = new List<string> { "Post" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>(),
|
AuthenticationProviderKey = "Test"
|
||||||
Provider = "IdentityServer",
|
|
||||||
IdentityServerConfig = new FileIdentityServerConfig{
|
|
||||||
ProviderRootUrl = _identityServerRootUrl,
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,7 +69,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
|
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
.And(x => _steps.GivenThePostHasContent("postContent"))
|
.And(x => _steps.GivenThePostHasContent("postContent"))
|
||||||
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Unauthorized))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Unauthorized))
|
||||||
@ -91,14 +93,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>(),
|
AuthenticationProviderKey = "Test"
|
||||||
Provider = "IdentityServer",
|
|
||||||
IdentityServerConfig = new FileIdentityServerConfig{
|
|
||||||
ProviderRootUrl = _identityServerRootUrl,
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,7 +103,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
@ -133,14 +128,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>(),
|
AuthenticationProviderKey = "Test"
|
||||||
Provider = "IdentityServer",
|
|
||||||
IdentityServerConfig = new FileIdentityServerConfig{
|
|
||||||
ProviderRootUrl = _identityServerRootUrl,
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,7 +138,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveATokenForApi2(_identityServerRootUrl))
|
.And(x => _steps.GivenIHaveATokenForApi2(_identityServerRootUrl))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Unauthorized))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Unauthorized))
|
||||||
@ -172,17 +160,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
DownstreamScheme = _downstreamServiceScheme,
|
DownstreamScheme = _downstreamServiceScheme,
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Post" },
|
UpstreamHttpMethod = new List<string> { "Post" },
|
||||||
|
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>(),
|
AuthenticationProviderKey = "Test"
|
||||||
Provider = "IdentityServer",
|
|
||||||
IdentityServerConfig = new FileIdentityServerConfig{
|
|
||||||
ProviderRootUrl = _identityServerRootUrl,
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,7 +172,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
|
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
|
||||||
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.And(x => _steps.GivenThePostHasContent("postContent"))
|
.And(x => _steps.GivenThePostHasContent("postContent"))
|
||||||
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
|
||||||
@ -217,14 +197,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
UpstreamHttpMethod = new List<string> { "Post" },
|
UpstreamHttpMethod = new List<string> { "Post" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>(),
|
AuthenticationProviderKey = "Test"
|
||||||
Provider = "IdentityServer",
|
|
||||||
IdentityServerConfig = new FileIdentityServerConfig{
|
|
||||||
ProviderRootUrl = _identityServerRootUrl,
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,7 +207,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
|
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
|
||||||
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.And(x => _steps.GivenThePostHasContent("postContent"))
|
.And(x => _steps.GivenThePostHasContent("postContent"))
|
||||||
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
|
||||||
@ -275,7 +248,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
services.AddLogging();
|
services.AddLogging();
|
||||||
services.AddIdentityServer()
|
services.AddIdentityServer()
|
||||||
.AddTemporarySigningCredential()
|
.AddDeveloperSigningCredential()
|
||||||
.AddInMemoryApiResources(new List<ApiResource>
|
.AddInMemoryApiResources(new List<ApiResource>
|
||||||
{
|
{
|
||||||
new ApiResource
|
new ApiResource
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using IdentityServer4.AccessTokenValidation;
|
||||||
using IdentityServer4.Models;
|
using IdentityServer4.Models;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
@ -22,10 +23,20 @@ namespace Ocelot.AcceptanceTests
|
|||||||
private IWebHost _servicebuilder;
|
private IWebHost _servicebuilder;
|
||||||
private IWebHost _identityServerBuilder;
|
private IWebHost _identityServerBuilder;
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
|
private Action<IdentityServerAuthenticationOptions> _options;
|
||||||
|
private string _identityServerRootUrl = "http://localhost:51888";
|
||||||
|
|
||||||
public AuthorisationTests()
|
public AuthorisationTests()
|
||||||
{
|
{
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
|
_options = o =>
|
||||||
|
{
|
||||||
|
o.Authority = _identityServerRootUrl;
|
||||||
|
o.ApiName = "api";
|
||||||
|
o.RequireHttpsMetadata = false;
|
||||||
|
o.SupportedTokens = SupportedTokens.Both;
|
||||||
|
o.ApiSecret = "secret";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -45,14 +56,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>(),
|
AuthenticationProviderKey = "Test"
|
||||||
Provider = "IdentityServer",
|
|
||||||
IdentityServerConfig = new FileIdentityServerConfig{
|
|
||||||
ProviderRootUrl = "http://localhost:51888",
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
AddHeadersToRequest =
|
AddHeadersToRequest =
|
||||||
{
|
{
|
||||||
@ -79,7 +83,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveAToken("http://localhost:51888"))
|
.And(x => _steps.GivenIHaveAToken("http://localhost:51888"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
@ -104,14 +108,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>(),
|
AuthenticationProviderKey = "Test"
|
||||||
Provider = "IdentityServer",
|
|
||||||
IdentityServerConfig = new FileIdentityServerConfig{
|
|
||||||
ProviderRootUrl = "http://localhost:51888",
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
AddHeadersToRequest =
|
AddHeadersToRequest =
|
||||||
{
|
{
|
||||||
@ -137,7 +134,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveAToken("http://localhost:51888"))
|
.And(x => _steps.GivenIHaveAToken("http://localhost:51888"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Forbidden))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Forbidden))
|
||||||
@ -161,15 +158,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
|
AuthenticationProviderKey = "Test",
|
||||||
AllowedScopes = new List<string>{ "api", "api.readOnly", "openid", "offline_access" },
|
AllowedScopes = new List<string>{ "api", "api.readOnly", "openid", "offline_access" },
|
||||||
Provider = "IdentityServer",
|
},
|
||||||
IdentityServerConfig = new FileIdentityServerConfig{
|
|
||||||
ProviderRootUrl = "http://localhost:51888",
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -178,7 +169,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveATokenForApiReadOnlyScope("http://localhost:51888"))
|
.And(x => _steps.GivenIHaveATokenForApiReadOnlyScope("http://localhost:51888"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
@ -202,15 +193,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
|
AuthenticationProviderKey = "Test",
|
||||||
AllowedScopes = new List<string>{ "api", "openid", "offline_access" },
|
AllowedScopes = new List<string>{ "api", "openid", "offline_access" },
|
||||||
Provider = "IdentityServer",
|
},
|
||||||
IdentityServerConfig = new FileIdentityServerConfig{
|
|
||||||
ProviderRootUrl = "http://localhost:51888",
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -219,7 +204,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveATokenForApiReadOnlyScope("http://localhost:51888"))
|
.And(x => _steps.GivenIHaveATokenForApiReadOnlyScope("http://localhost:51888"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Forbidden))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Forbidden))
|
||||||
@ -259,7 +244,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
services.AddLogging();
|
services.AddLogging();
|
||||||
services.AddIdentityServer()
|
services.AddIdentityServer()
|
||||||
.AddTemporarySigningCredential()
|
.AddDeveloperSigningCredential()
|
||||||
.AddInMemoryApiResources(new List<ApiResource>
|
.AddInMemoryApiResources(new List<ApiResource>
|
||||||
{
|
{
|
||||||
new ApiResource
|
new ApiResource
|
||||||
|
@ -40,7 +40,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products/1", 200, "Some Product"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
||||||
@ -68,7 +68,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products/1", 200, "Some Product"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
||||||
@ -96,7 +96,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products/1", 200, "Some Product"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
||||||
@ -124,7 +124,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products/1", 200, "Some Product"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
||||||
@ -152,7 +152,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products/1", 200, "Some Product"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
||||||
@ -180,7 +180,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products/1", 200, "Some Product"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
||||||
@ -188,16 +188,17 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_builder = new WebHostBuilder()
|
||||||
.UseUrls(url)
|
.UseUrls(baseUrl)
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
.UseIISIntegration()
|
.UseIISIntegration()
|
||||||
.UseUrls(url)
|
.UseUrls(baseUrl)
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
|
app.UsePathBase(basePath);
|
||||||
app.Run(async context =>
|
app.Run(async context =>
|
||||||
{
|
{
|
||||||
context.Response.StatusCode = statusCode;
|
context.Response.StatusCode = statusCode;
|
||||||
|
@ -4,6 +4,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using IdentityServer4.AccessTokenValidation;
|
||||||
using IdentityServer4.Models;
|
using IdentityServer4.Models;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
@ -24,10 +25,20 @@ namespace Ocelot.AcceptanceTests
|
|||||||
private IWebHost _servicebuilder;
|
private IWebHost _servicebuilder;
|
||||||
private IWebHost _identityServerBuilder;
|
private IWebHost _identityServerBuilder;
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
|
private Action<IdentityServerAuthenticationOptions> _options;
|
||||||
|
private string _identityServerRootUrl = "http://localhost:52888";
|
||||||
|
|
||||||
public ClaimsToHeadersForwardingTests()
|
public ClaimsToHeadersForwardingTests()
|
||||||
{
|
{
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
|
_options = o =>
|
||||||
|
{
|
||||||
|
o.Authority = _identityServerRootUrl;
|
||||||
|
o.ApiName = "api";
|
||||||
|
o.RequireHttpsMetadata = false;
|
||||||
|
o.SupportedTokens = SupportedTokens.Both;
|
||||||
|
o.ApiSecret = "secret";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -59,17 +70,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
|
AuthenticationProviderKey = "Test",
|
||||||
AllowedScopes = new List<string>
|
AllowedScopes = new List<string>
|
||||||
{
|
{
|
||||||
"openid", "offline_access", "api"
|
"openid", "offline_access", "api"
|
||||||
},
|
},
|
||||||
Provider = "IdentityServer",
|
|
||||||
IdentityServerConfig = new FileIdentityServerConfig{
|
|
||||||
ProviderRootUrl = "http://localhost:52888",
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
AddHeadersToRequest =
|
AddHeadersToRequest =
|
||||||
{
|
{
|
||||||
@ -86,7 +91,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:52876", 200))
|
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:52876", 200))
|
||||||
.And(x => _steps.GivenIHaveAToken("http://localhost:52888"))
|
.And(x => _steps.GivenIHaveAToken("http://localhost:52888"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
@ -133,7 +138,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
services.AddLogging();
|
services.AddLogging();
|
||||||
services.AddIdentityServer()
|
services.AddIdentityServer()
|
||||||
.AddTemporarySigningCredential()
|
.AddDeveloperSigningCredential()
|
||||||
.AddInMemoryApiResources(new List<ApiResource>
|
.AddInMemoryApiResources(new List<ApiResource>
|
||||||
{
|
{
|
||||||
new ApiResource
|
new ApiResource
|
||||||
|
@ -4,6 +4,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using IdentityServer4.AccessTokenValidation;
|
||||||
using IdentityServer4.Models;
|
using IdentityServer4.Models;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
@ -24,10 +25,20 @@ namespace Ocelot.AcceptanceTests
|
|||||||
private IWebHost _servicebuilder;
|
private IWebHost _servicebuilder;
|
||||||
private IWebHost _identityServerBuilder;
|
private IWebHost _identityServerBuilder;
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
|
private Action<IdentityServerAuthenticationOptions> _options;
|
||||||
|
private string _identityServerRootUrl = "http://localhost:57888";
|
||||||
|
|
||||||
public ClaimsToQueryStringForwardingTests()
|
public ClaimsToQueryStringForwardingTests()
|
||||||
{
|
{
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
|
_options = o =>
|
||||||
|
{
|
||||||
|
o.Authority = _identityServerRootUrl;
|
||||||
|
o.ApiName = "api";
|
||||||
|
o.RequireHttpsMetadata = false;
|
||||||
|
o.SupportedTokens = SupportedTokens.Both;
|
||||||
|
o.ApiSecret = "secret";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -59,17 +70,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
|
AuthenticationProviderKey = "Test",
|
||||||
AllowedScopes = new List<string>
|
AllowedScopes = new List<string>
|
||||||
{
|
{
|
||||||
"openid", "offline_access", "api"
|
"openid", "offline_access", "api"
|
||||||
},
|
},
|
||||||
Provider = "IdentityServer",
|
|
||||||
IdentityServerConfig = new FileIdentityServerConfig{
|
|
||||||
ProviderRootUrl = "http://localhost:57888",
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
AddQueriesToRequest =
|
AddQueriesToRequest =
|
||||||
{
|
{
|
||||||
@ -86,7 +91,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:57876", 200))
|
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:57876", 200))
|
||||||
.And(x => _steps.GivenIHaveAToken("http://localhost:57888"))
|
.And(x => _steps.GivenIHaveAToken("http://localhost:57888"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
@ -140,7 +145,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
services.AddLogging();
|
services.AddLogging();
|
||||||
services.AddIdentityServer()
|
services.AddIdentityServer()
|
||||||
.AddTemporarySigningCredential()
|
.AddDeveloperSigningCredential()
|
||||||
.AddInMemoryApiResources(new List<ApiResource>
|
.AddInMemoryApiResources(new List<ApiResource>
|
||||||
{
|
{
|
||||||
new ApiResource
|
new ApiResource
|
||||||
|
@ -75,7 +75,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/ClientRateLimit"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/ClientRateLimit"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit",1))
|
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit",1))
|
||||||
@ -128,7 +128,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/ClientRateLimit"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/ClientRateLimit"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit", 4))
|
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit", 4))
|
||||||
@ -137,16 +137,17 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url)
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_builder = new WebHostBuilder()
|
||||||
.UseUrls(url)
|
.UseUrls(baseUrl)
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
.UseIISIntegration()
|
.UseIISIntegration()
|
||||||
.UseUrls(url)
|
.UseUrls(baseUrl)
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
|
app.UsePathBase(basePath);
|
||||||
app.Run(context =>
|
app.Run(context =>
|
||||||
{
|
{
|
||||||
_counterOne++;
|
_counterOne++;
|
||||||
|
@ -3,15 +3,12 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Consul;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Ocelot.Authentication.JsonConverters;
|
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Configuration.Repository;
|
|
||||||
using Ocelot.ServiceDiscovery;
|
using Ocelot.ServiceDiscovery;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
@ -105,9 +102,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
var json = reader.ReadToEnd();
|
var json = reader.ReadToEnd();
|
||||||
|
|
||||||
var settings = new JsonSerializerSettings();
|
_config = JsonConvert.DeserializeObject<OcelotConfiguration>(json);
|
||||||
settings.Converters.Add(new AuthenticationConfigConverter());
|
|
||||||
_config = JsonConvert.DeserializeObject<OcelotConfiguration>(json, settings);
|
|
||||||
|
|
||||||
var response = JsonConvert.SerializeObject(true);
|
var response = JsonConvert.SerializeObject(true);
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = "41879/",
|
DownstreamPathTemplate = "/41879/",
|
||||||
DownstreamPort = 41879,
|
DownstreamPort = 41879,
|
||||||
DownstreamScheme = "http",
|
DownstreamScheme = "http",
|
||||||
DownstreamHost = "localhost",
|
DownstreamHost = "localhost",
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
|
||||||
<AssemblyName>Ocelot.AcceptanceTests</AssemblyName>
|
<AssemblyName>Ocelot.AcceptanceTests</AssemblyName>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<PackageId>Ocelot.AcceptanceTests</PackageId>
|
<PackageId>Ocelot.AcceptanceTests</PackageId>
|
||||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||||
<RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
|
||||||
<RuntimeFrameworkVersion>1.1.1</RuntimeFrameworkVersion>
|
|
||||||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
||||||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
||||||
@ -30,28 +30,23 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.MiddlewareAnalysis" Version="1.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-preview-20170106-08" />
|
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.0" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta2-build1317" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20171031-01" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.1.1" />
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.0" />
|
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="1.1.1" />
|
<PackageReference Include="Shouldly" Version="3.0.0-beta0003" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.1.1" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="1.1.1" />
|
|
||||||
<PackageReference Include="Shouldly" Version="2.8.2" />
|
|
||||||
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
||||||
<PackageReference Include="Consul" Version="0.7.2.1" />
|
<PackageReference Include="Consul" Version="0.7.2.3" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="1.1.1" />
|
<PackageReference Include="xunit" Version="2.3.1" />
|
||||||
<PackageReference Include="xunit" Version="2.3.0-beta2-build3683" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -98,7 +98,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
DownstreamScheme = "http",
|
DownstreamScheme = "http",
|
||||||
DownstreamHost = "localhost",
|
DownstreamHost = "localhost",
|
||||||
DownstreamPort = 51880,
|
DownstreamPort = 51880,
|
||||||
UpstreamPathTemplate = "working",
|
UpstreamPathTemplate = "/working",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Builder;
|
|||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
|
using Shouldly;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
@ -15,6 +16,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
private IWebHost _builder;
|
private IWebHost _builder;
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
|
private string _downstreamPath;
|
||||||
|
|
||||||
public RoutingTests()
|
public RoutingTests()
|
||||||
{
|
{
|
||||||
@ -50,7 +52,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", 200, "Hello from Laura"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
@ -59,6 +61,47 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void bug()
|
||||||
|
{
|
||||||
|
var configuration = new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/api/v1/vacancy",
|
||||||
|
DownstreamScheme = "http",
|
||||||
|
DownstreamHost = "localhost",
|
||||||
|
DownstreamPort = 51879,
|
||||||
|
UpstreamPathTemplate = "/vacancy/",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Options", "Put", "Get", "Post", "Delete" },
|
||||||
|
ServiceName = "botCore",
|
||||||
|
LoadBalancer = "LeastConnection"
|
||||||
|
},
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/api/v1/vacancy/{vacancyId}",
|
||||||
|
DownstreamScheme = "http",
|
||||||
|
DownstreamHost = "localhost",
|
||||||
|
DownstreamPort = 51879,
|
||||||
|
UpstreamPathTemplate = "/vacancy/{vacancyId}",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Options", "Put", "Get", "Post", "Delete" },
|
||||||
|
ServiceName = "botCore",
|
||||||
|
LoadBalancer = "LeastConnection"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/v1/vacancy/1", 200, "Hello from Laura"))
|
||||||
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/vacancy/1"))
|
||||||
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
|
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_200_when_path_missing_forward_slash_as_first_char()
|
public void should_return_response_200_when_path_missing_forward_slash_as_first_char()
|
||||||
{
|
{
|
||||||
@ -68,7 +111,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = "api/products",
|
DownstreamPathTemplate = "/api/products",
|
||||||
DownstreamScheme = "http",
|
DownstreamScheme = "http",
|
||||||
DownstreamHost = "localhost",
|
DownstreamHost = "localhost",
|
||||||
DownstreamPort = 51879,
|
DownstreamPort = 51879,
|
||||||
@ -78,7 +121,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products", 200, "Hello from Laura"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
@ -106,7 +149,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products", 200, "Hello from Laura"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
@ -134,7 +177,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/products", 200, "Hello from Laura"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/products", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/products"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/products"))
|
||||||
@ -162,7 +205,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/products", 200, "Hello from Laura"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/products", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/products/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/products/"))
|
||||||
@ -196,7 +239,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/products", 200, "Hello from Laura"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/products", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/products/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/products/"))
|
||||||
@ -223,7 +266,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products/1", 200, "Some Product"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/products/1"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/products/1"))
|
||||||
@ -232,6 +275,34 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_not_add_trailing_slash_to_downstream_url()
|
||||||
|
{
|
||||||
|
var configuration = new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/api/products/{productId}",
|
||||||
|
DownstreamScheme = "http",
|
||||||
|
DownstreamHost = "localhost",
|
||||||
|
DownstreamPort = 51879,
|
||||||
|
UpstreamPathTemplate = "/products/{productId}",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.Given(x => GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
|
||||||
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/products/1"))
|
||||||
|
.Then(x => ThenTheDownstreamUrlPathShouldBe("/api/products/1"))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_201_with_simple_url()
|
public void should_return_response_201_with_simple_url()
|
||||||
{
|
{
|
||||||
@ -251,7 +322,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", 201, string.Empty))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "", 201, string.Empty))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.And(x => _steps.GivenThePostHasContent("postContent"))
|
.And(x => _steps.GivenThePostHasContent("postContent"))
|
||||||
@ -279,7 +350,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", 200, "Hello from Laura"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/newThing?DeviceType=IphoneApp&Browser=moonpigIphone&BrowserString=-&CountryCode=123&DeviceName=iPhone 5 (GSM+CDMA)&OperatingSystem=iPhone OS 7.1.2&BrowserVersion=3708AdHoc&ipAddress=-"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/newThing?DeviceType=IphoneApp&Browser=moonpigIphone&BrowserString=-&CountryCode=123&DeviceName=iPhone 5 (GSM+CDMA)&OperatingSystem=iPhone OS 7.1.2&BrowserVersion=3708AdHoc&ipAddress=-"))
|
||||||
@ -307,7 +378,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/myApp1Name/api/products/1", 200, "Some Product"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/myApp1Name/api/products/1", 200, "Some Product"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/myApp1Name/api/products/1"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/myApp1Name/api/products/1"))
|
||||||
@ -335,7 +406,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", 201, string.Empty))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "", 201, string.Empty))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.And(x => _steps.GivenThePostHasContent("postContent"))
|
.And(x => _steps.GivenThePostHasContent("postContent"))
|
||||||
@ -363,7 +434,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", 200, "Hello from Laura"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
@ -372,18 +443,59 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
|
[Fact]
|
||||||
|
public void should_return_404_when_calling_upstream_route_with_no_matching_downstream_re_route_github_issue_134()
|
||||||
|
{
|
||||||
|
var configuration = new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/api/v1/vacancy",
|
||||||
|
DownstreamScheme = "http",
|
||||||
|
DownstreamHost = "localhost",
|
||||||
|
DownstreamPort = 51879,
|
||||||
|
UpstreamPathTemplate = "/vacancy/",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Options", "Put", "Get", "Post", "Delete" },
|
||||||
|
ServiceName = "botCore",
|
||||||
|
LoadBalancer = "LeastConnection"
|
||||||
|
},
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/api/v1/vacancy/{vacancyId}",
|
||||||
|
DownstreamScheme = "http",
|
||||||
|
DownstreamHost = "localhost",
|
||||||
|
DownstreamPort = 51879,
|
||||||
|
UpstreamPathTemplate = "/vacancy/{vacancyId}",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Options", "Put", "Get", "Post", "Delete" },
|
||||||
|
ServiceName = "botCore",
|
||||||
|
LoadBalancer = "LeastConnection"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/v1/vacancy/1", 200, "Hello from Laura"))
|
||||||
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("api/vacancy/1"))
|
||||||
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.NotFound))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_builder = new WebHostBuilder()
|
||||||
.UseUrls(url)
|
.UseUrls(baseUrl)
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
.UseIISIntegration()
|
.UseIISIntegration()
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
|
app.UsePathBase(basePath);
|
||||||
app.Run(async context =>
|
app.Run(async context =>
|
||||||
{
|
{
|
||||||
|
_downstreamPath = context.Request.PathBase.Value;
|
||||||
context.Response.StatusCode = statusCode;
|
context.Response.StatusCode = statusCode;
|
||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
});
|
});
|
||||||
@ -393,6 +505,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
_builder.Start();
|
_builder.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void ThenTheDownstreamUrlPathShouldBe(string expectedDownstreamPath)
|
||||||
|
{
|
||||||
|
_downstreamPath.ShouldBe(expectedDownstreamPath);
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_builder?.Dispose();
|
_builder?.Dispose();
|
||||||
|
@ -8,6 +8,8 @@ using System.Net.Http.Headers;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using CacheManager.Core;
|
using CacheManager.Core;
|
||||||
|
using IdentityServer4.AccessTokenValidation;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.TestHost;
|
using Microsoft.AspNetCore.TestHost;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
@ -17,7 +19,6 @@ using Newtonsoft.Json;
|
|||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Configuration.Repository;
|
using Ocelot.Configuration.Repository;
|
||||||
using Ocelot.DependencyInjection;
|
using Ocelot.DependencyInjection;
|
||||||
using Ocelot.ManualTest;
|
|
||||||
using Ocelot.Middleware;
|
using Ocelot.Middleware;
|
||||||
using Ocelot.ServiceDiscovery;
|
using Ocelot.ServiceDiscovery;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
@ -86,6 +87,26 @@ namespace Ocelot.AcceptanceTests
|
|||||||
_ocelotClient = _ocelotServer.CreateClient();
|
_ocelotClient = _ocelotServer.CreateClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is annoying cos it should be in the constructor but we need to set up the file before calling startup so its a step.
|
||||||
|
/// </summary>
|
||||||
|
public void GivenOcelotIsRunning(Action<IdentityServerAuthenticationOptions> options, string authenticationProviderKey)
|
||||||
|
{
|
||||||
|
_webHostBuilder = new WebHostBuilder();
|
||||||
|
|
||||||
|
_webHostBuilder.ConfigureServices(s =>
|
||||||
|
{
|
||||||
|
s.AddSingleton(_webHostBuilder);
|
||||||
|
s.AddAuthentication()
|
||||||
|
.AddIdentityServerAuthentication(authenticationProviderKey, options);
|
||||||
|
});
|
||||||
|
|
||||||
|
_ocelotServer = new TestServer(_webHostBuilder
|
||||||
|
.UseStartup<Startup>());
|
||||||
|
|
||||||
|
_ocelotClient = _ocelotServer.CreateClient();
|
||||||
|
}
|
||||||
|
|
||||||
public void GivenOcelotIsRunningUsingConsulToStoreConfig(ConsulRegistryConfiguration consulConfig)
|
public void GivenOcelotIsRunningUsingConsulToStoreConfig(ConsulRegistryConfiguration consulConfig)
|
||||||
{
|
{
|
||||||
_webHostBuilder = new WebHostBuilder();
|
_webHostBuilder = new WebHostBuilder();
|
||||||
@ -135,9 +156,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.AddEnvironmentVariables();
|
.AddEnvironmentVariables();
|
||||||
|
|
||||||
var configuration = builder.Build();
|
var configuration = builder.Build();
|
||||||
|
|
||||||
_webHostBuilder = new WebHostBuilder();
|
_webHostBuilder = new WebHostBuilder();
|
||||||
|
|
||||||
_webHostBuilder.ConfigureServices(s =>
|
_webHostBuilder.ConfigureServices(s =>
|
||||||
{
|
{
|
||||||
s.AddSingleton(_webHostBuilder);
|
s.AddSingleton(_webHostBuilder);
|
||||||
@ -160,7 +179,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
})
|
})
|
||||||
.ConfigureLogging(l =>
|
.ConfigureLogging(l =>
|
||||||
{
|
{
|
||||||
l.AddConsole(configuration.GetSection("Logging"));
|
l.AddConsole();
|
||||||
l.AddDebug();
|
l.AddDebug();
|
||||||
})
|
})
|
||||||
.Configure(a =>
|
.Configure(a =>
|
||||||
@ -362,4 +381,42 @@ namespace Ocelot.AcceptanceTests
|
|||||||
_response.Headers.GetValues(RequestIdKey).First().ShouldBe(expected);
|
_response.Headers.GetValues(RequestIdKey).First().ShouldBe(expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public Startup(IHostingEnvironment env)
|
||||||
|
{
|
||||||
|
var builder = new ConfigurationBuilder()
|
||||||
|
.SetBasePath(env.ContentRootPath)
|
||||||
|
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
|
||||||
|
.AddJsonFile("configuration.json")
|
||||||
|
.AddEnvironmentVariables();
|
||||||
|
|
||||||
|
Configuration = builder.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IConfigurationRoot Configuration { get; }
|
||||||
|
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
Action<ConfigurationBuilderCachePart> settings = (x) =>
|
||||||
|
{
|
||||||
|
x.WithMicrosoftLogging(log =>
|
||||||
|
{
|
||||||
|
log.AddConsole(LogLevel.Debug);
|
||||||
|
})
|
||||||
|
.WithDictionaryHandle();
|
||||||
|
};
|
||||||
|
|
||||||
|
services.AddOcelot(Configuration, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
||||||
|
{
|
||||||
|
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
|
||||||
|
|
||||||
|
app.UseOcelot().Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
|
||||||
<AssemblyName>Ocelot.Benchmarks</AssemblyName>
|
<AssemblyName>Ocelot.Benchmarks</AssemblyName>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<PackageId>Ocelot.Benchmarks</PackageId>
|
<PackageId>Ocelot.Benchmarks</PackageId>
|
||||||
@ -17,7 +18,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BenchmarkDotNet" Version="0.10.2" />
|
<PackageReference Include="BenchmarkDotNet" Version="0.10.9" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -9,7 +9,6 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Ocelot.Cache;
|
using Ocelot.Cache;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.ManualTest;
|
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
|
||||||
<AssemblyName>Ocelot.IntegrationTests</AssemblyName>
|
<AssemblyName>Ocelot.IntegrationTests</AssemblyName>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<PackageId>Ocelot.IntegrationTests</PackageId>
|
<PackageId>Ocelot.IntegrationTests</PackageId>
|
||||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||||
<RuntimeIdentifiers>win10-x64;osx.10.11-x64;osx.10.12-x64;win7-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win10-x64;osx.10.11-x64;osx.10.12-x64;win7-x64</RuntimeIdentifiers>
|
||||||
<RuntimeFrameworkVersion>1.1.1</RuntimeFrameworkVersion>
|
|
||||||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
||||||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
||||||
@ -30,27 +30,22 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.MiddlewareAnalysis" Version="1.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-preview-20170106-08" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20171031-01" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta2-build1317" />
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="1.1.1" />
|
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="1.1.1" />
|
<PackageReference Include="xunit" Version="2.3.1" />
|
||||||
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.0" />
|
<PackageReference Include="IdentityServer4" Version="2.0.2" />
|
||||||
<PackageReference Include="xunit" Version="2.3.0-beta2-build3683" />
|
<PackageReference Include="Shouldly" Version="3.0.0-beta0003" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="1.1.1" />
|
|
||||||
<PackageReference Include="IdentityServer4" Version="1.5.1" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.1.1" />
|
|
||||||
<PackageReference Include="Shouldly" Version="2.8.2" />
|
|
||||||
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
||||||
<PackageReference Include="Consul" Version="0.7.2.1" />
|
<PackageReference Include="Consul" Version="0.7.2.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
51
test/Ocelot.IntegrationTests/Startup.cs
Normal file
51
test/Ocelot.IntegrationTests/Startup.cs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
using System;
|
||||||
|
using CacheManager.Core;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Ocelot.DependencyInjection;
|
||||||
|
using Ocelot.Middleware;
|
||||||
|
using ConfigurationBuilder = Microsoft.Extensions.Configuration.ConfigurationBuilder;
|
||||||
|
|
||||||
|
namespace Ocelot.IntegrationTests
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public Startup(IHostingEnvironment env)
|
||||||
|
{
|
||||||
|
var builder = new ConfigurationBuilder()
|
||||||
|
.SetBasePath(env.ContentRootPath)
|
||||||
|
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||||
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
|
||||||
|
.AddJsonFile("configuration.json")
|
||||||
|
.AddEnvironmentVariables();
|
||||||
|
|
||||||
|
Configuration = builder.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IConfigurationRoot Configuration { get; }
|
||||||
|
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
Action<ConfigurationBuilderCachePart> settings = (x) =>
|
||||||
|
{
|
||||||
|
x.WithMicrosoftLogging(log =>
|
||||||
|
{
|
||||||
|
log.AddConsole(LogLevel.Debug);
|
||||||
|
})
|
||||||
|
.WithDictionaryHandle();
|
||||||
|
};
|
||||||
|
|
||||||
|
services.AddOcelot(Configuration, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
||||||
|
{
|
||||||
|
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
|
||||||
|
|
||||||
|
app.UseOcelot().Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.ManualTest;
|
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
|
||||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||||
<AssemblyName>Ocelot.ManualTest</AssemblyName>
|
<AssemblyName>Ocelot.ManualTest</AssemblyName>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<PackageId>Ocelot.ManualTest</PackageId>
|
<PackageId>Ocelot.ManualTest</PackageId>
|
||||||
<RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
|
||||||
<RuntimeFrameworkVersion>1.1.1</RuntimeFrameworkVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -17,24 +17,27 @@
|
|||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="configuration.json;appsettings.json;idsrv3test.pfx">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
|
<ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.MiddlewareAnalysis" Version="1.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="1.1.1" />
|
<PackageReference Include="Consul" Version="0.7.2.3" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.1.1" />
|
<PackageReference Include="Polly" Version="5.3.1" />
|
||||||
<PackageReference Include="Consul" Version="0.7.2.1" />
|
|
||||||
<PackageReference Include="Polly" Version="5.0.3" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="1.1.1" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -10,175 +10,362 @@
|
|||||||
"e8825dc3-4137-99a7-0000-ef5786610dc3",
|
"e8825dc3-4137-99a7-0000-ef5786610dc3",
|
||||||
"fddfc4fa-5114-69e3-4744-203ed71a526b",
|
"fddfc4fa-5114-69e3-4744-203ed71a526b",
|
||||||
"c45d30d7-d9c4-fa05-8110-d6e769bb6ff9",
|
"c45d30d7-d9c4-fa05-8110-d6e769bb6ff9",
|
||||||
"4684c2fa-f38c-c193-5f55-bf563a1978c6"
|
"4684c2fa-f38c-c193-5f55-bf563a1978c6",
|
||||||
|
"37bfa9f1-fe29-6a68-e558-66d125d2c96f",
|
||||||
|
"5f308240-79e3-cf74-7a6b-fe462f0d54f1",
|
||||||
|
"178f16da-c61b-c881-1c33-9d64a56851a4"
|
||||||
],
|
],
|
||||||
"folders": [],
|
"folders": [],
|
||||||
"timestamp": 1477767328599,
|
"folders_order": [],
|
||||||
|
"timestamp": 0,
|
||||||
"owner": "212120",
|
"owner": "212120",
|
||||||
"public": false,
|
"public": false,
|
||||||
"requests": [
|
"requests": [
|
||||||
{
|
{
|
||||||
|
"folder": null,
|
||||||
"id": "09af8dda-a9cb-20d2-5ee3-0a3023773a1a",
|
"id": "09af8dda-a9cb-20d2-5ee3-0a3023773a1a",
|
||||||
"headers": "",
|
|
||||||
"url": "http://localhost:5000/comments?postId=1",
|
|
||||||
"pathVariables": {},
|
|
||||||
"preRequestScript": null,
|
|
||||||
"method": "GET",
|
|
||||||
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375",
|
|
||||||
"data": null,
|
|
||||||
"dataMode": "params",
|
|
||||||
"name": "GET http://localhost:5000/comments?postId=1",
|
"name": "GET http://localhost:5000/comments?postId=1",
|
||||||
"description": "",
|
|
||||||
"descriptionFormat": "html",
|
|
||||||
"time": 1477768105592,
|
|
||||||
"version": 2,
|
|
||||||
"responses": [],
|
|
||||||
"tests": null,
|
|
||||||
"currentHelper": "normal",
|
|
||||||
"helperAttributes": {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "4684c2fa-f38c-c193-5f55-bf563a1978c6",
|
|
||||||
"headers": "",
|
|
||||||
"url": "http://localhost:5000/posts/1",
|
|
||||||
"pathVariables": {},
|
|
||||||
"preRequestScript": null,
|
|
||||||
"method": "DELETE",
|
|
||||||
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375",
|
|
||||||
"data": null,
|
|
||||||
"dataMode": "params",
|
"dataMode": "params",
|
||||||
"name": "DELETE http://localhost:5000/posts/1",
|
"data": null,
|
||||||
"description": "",
|
"rawModeData": null,
|
||||||
"descriptionFormat": "html",
|
"descriptionFormat": "html",
|
||||||
"time": 1477768404376,
|
"description": "",
|
||||||
"version": 2,
|
|
||||||
"responses": [],
|
|
||||||
"tests": null,
|
|
||||||
"currentHelper": "normal",
|
|
||||||
"helperAttributes": {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "a1c95935-ed18-d5dc-bcb8-a3db8ba1934f",
|
|
||||||
"headers": "",
|
"headers": "",
|
||||||
"url": "http://localhost:5000/posts",
|
|
||||||
"pathVariables": {},
|
|
||||||
"preRequestScript": null,
|
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375",
|
"pathVariables": {},
|
||||||
"data": null,
|
"url": "http://localhost:5000/comments?postId=1",
|
||||||
"dataMode": "params",
|
"preRequestScript": null,
|
||||||
"name": "GET http://localhost:5000/posts",
|
|
||||||
"description": "",
|
|
||||||
"descriptionFormat": "html",
|
|
||||||
"time": 1477768007806,
|
|
||||||
"version": 2,
|
|
||||||
"responses": [],
|
|
||||||
"tests": null,
|
"tests": null,
|
||||||
"currentHelper": "normal",
|
"currentHelper": "normal",
|
||||||
"helperAttributes": {}
|
"helperAttributes": "{}",
|
||||||
|
"queryParams": [],
|
||||||
|
"headerData": [],
|
||||||
|
"pathVariableData": [],
|
||||||
|
"responses": [],
|
||||||
|
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "c4494401-3985-a5bf-71fb-6e4171384ac6",
|
"id": "178f16da-c61b-c881-1c33-9d64a56851a4",
|
||||||
"headers": "",
|
"headers": "Authorization: Bearer {{AccessToken}}\n",
|
||||||
"url": "http://localhost:5000/posts/1/comments",
|
"headerData": [
|
||||||
"pathVariables": {},
|
{
|
||||||
|
"key": "Authorization",
|
||||||
|
"value": "Bearer {{AccessToken}}",
|
||||||
|
"enabled": true,
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": "http://localhost:5000/administration/configuration",
|
||||||
|
"folder": null,
|
||||||
|
"queryParams": [],
|
||||||
"preRequestScript": null,
|
"preRequestScript": null,
|
||||||
|
"pathVariables": {},
|
||||||
|
"pathVariableData": [],
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375",
|
|
||||||
"data": null,
|
"data": null,
|
||||||
"dataMode": "params",
|
"dataMode": "params",
|
||||||
"name": "GET http://localhost:5000/posts/1/comments",
|
|
||||||
"description": "",
|
|
||||||
"descriptionFormat": "html",
|
|
||||||
"time": 1477768043524,
|
|
||||||
"version": 2,
|
|
||||||
"responses": [],
|
|
||||||
"tests": null,
|
"tests": null,
|
||||||
"currentHelper": "normal",
|
"currentHelper": "normal",
|
||||||
"helperAttributes": {}
|
"helperAttributes": "{}",
|
||||||
},
|
"time": 1508849878025,
|
||||||
{
|
"name": "GET http://localhost:5000/admin/configuration",
|
||||||
"id": "c45d30d7-d9c4-fa05-8110-d6e769bb6ff9",
|
"description": "",
|
||||||
"headers": "",
|
|
||||||
"url": "http://localhost:5000/posts/1",
|
|
||||||
"pathVariables": {},
|
|
||||||
"preRequestScript": null,
|
|
||||||
"method": "PATCH",
|
|
||||||
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375",
|
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375",
|
||||||
"data": [],
|
|
||||||
"dataMode": "raw",
|
|
||||||
"name": "PATCH http://localhost:5000/posts/1",
|
|
||||||
"description": "",
|
|
||||||
"descriptionFormat": "html",
|
|
||||||
"time": 1477768379775,
|
|
||||||
"version": 2,
|
|
||||||
"responses": [],
|
"responses": [],
|
||||||
"tests": null,
|
"isFromCollection": true,
|
||||||
"currentHelper": "normal",
|
"collectionRequestId": "178f16da-c61b-c881-1c33-9d64a56851a4",
|
||||||
"helperAttributes": {},
|
"rawModeData": null,
|
||||||
"rawModeData": "{\n \"title\": \"gfdgsgsdgsdfgsdfgdfg\",\n}"
|
"descriptionFormat": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "e8825dc3-4137-99a7-0000-ef5786610dc3",
|
"id": "37bfa9f1-fe29-6a68-e558-66d125d2c96f",
|
||||||
"headers": "",
|
"headers": "",
|
||||||
"url": "http://localhost:5000/posts",
|
"headerData": [],
|
||||||
"pathVariables": {},
|
"url": "http://localhost:5000/administration/connect/token",
|
||||||
|
"folder": null,
|
||||||
|
"queryParams": [],
|
||||||
"preRequestScript": null,
|
"preRequestScript": null,
|
||||||
|
"pathVariables": {},
|
||||||
|
"pathVariableData": [],
|
||||||
"method": "POST",
|
"method": "POST",
|
||||||
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375",
|
"data": [
|
||||||
"data": [],
|
{
|
||||||
"dataMode": "raw",
|
"key": "client_id",
|
||||||
"name": "POST http://localhost:5000/posts/1",
|
"value": "admin",
|
||||||
"description": "",
|
"type": "text",
|
||||||
"descriptionFormat": "html",
|
"enabled": true
|
||||||
"time": 1477768186023,
|
|
||||||
"version": 2,
|
|
||||||
"responses": [],
|
|
||||||
"tests": null,
|
|
||||||
"currentHelper": "normal",
|
|
||||||
"helperAttributes": {},
|
|
||||||
"rawModeData": "{\n \"userId\": 1,\n \"title\": \"test\",\n \"body\": \"test\"\n}"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "ea0ed57a-2cb9-8acc-47dd-006b8db2f1b2",
|
"key": "client_secret",
|
||||||
"headers": "",
|
"value": "secret",
|
||||||
"url": "http://localhost:5000/posts/1",
|
"type": "text",
|
||||||
"pathVariables": {},
|
"enabled": true
|
||||||
"preRequestScript": null,
|
},
|
||||||
"method": "GET",
|
{
|
||||||
|
"key": "scope",
|
||||||
|
"value": "admin",
|
||||||
|
"type": "text",
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "username",
|
||||||
|
"value": "admin",
|
||||||
|
"type": "text",
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "password",
|
||||||
|
"value": "secret",
|
||||||
|
"type": "text",
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "grant_type",
|
||||||
|
"value": "password",
|
||||||
|
"type": "text",
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dataMode": "params",
|
||||||
|
"tests": "var jsonData = JSON.parse(responseBody);\npostman.setGlobalVariable(\"AccessToken\", jsonData.access_token);\npostman.setGlobalVariable(\"RefreshToken\", jsonData.refresh_token);",
|
||||||
|
"currentHelper": "normal",
|
||||||
|
"helperAttributes": "{}",
|
||||||
|
"time": 1506359585080,
|
||||||
|
"name": "POST http://localhost:5000/admin/connect/token copy",
|
||||||
|
"description": "",
|
||||||
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375",
|
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375",
|
||||||
|
"responses": [],
|
||||||
|
"isFromCollection": true,
|
||||||
|
"collectionRequestId": "37bfa9f1-fe29-6a68-e558-66d125d2c96f",
|
||||||
|
"rawModeData": null,
|
||||||
|
"descriptionFormat": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"folder": null,
|
||||||
|
"id": "4684c2fa-f38c-c193-5f55-bf563a1978c6",
|
||||||
|
"name": "DELETE http://localhost:5000/posts/1",
|
||||||
|
"dataMode": "params",
|
||||||
|
"data": null,
|
||||||
|
"rawModeData": null,
|
||||||
|
"descriptionFormat": "html",
|
||||||
|
"description": "",
|
||||||
|
"headers": "",
|
||||||
|
"method": "DELETE",
|
||||||
|
"pathVariables": {},
|
||||||
|
"url": "http://localhost:5000/posts/1",
|
||||||
|
"preRequestScript": null,
|
||||||
|
"tests": null,
|
||||||
|
"currentHelper": "normal",
|
||||||
|
"helperAttributes": "{}",
|
||||||
|
"queryParams": [],
|
||||||
|
"headerData": [],
|
||||||
|
"pathVariableData": [],
|
||||||
|
"responses": [],
|
||||||
|
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5f308240-79e3-cf74-7a6b-fe462f0d54f1",
|
||||||
|
"headers": "Authorization: Bearer {{AccessToken}}\n",
|
||||||
|
"headerData": [
|
||||||
|
{
|
||||||
|
"key": "Authorization",
|
||||||
|
"value": "Bearer {{AccessToken}}",
|
||||||
|
"description": "",
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": "http://localhost:5000/administration/.well-known/openid-configuration",
|
||||||
|
"folder": null,
|
||||||
|
"queryParams": [],
|
||||||
|
"preRequestScript": null,
|
||||||
|
"pathVariables": {},
|
||||||
|
"pathVariableData": [],
|
||||||
|
"method": "GET",
|
||||||
"data": null,
|
"data": null,
|
||||||
"dataMode": "params",
|
"dataMode": "params",
|
||||||
"name": "GET http://localhost:5000/posts/1",
|
|
||||||
"description": "",
|
|
||||||
"descriptionFormat": "html",
|
|
||||||
"time": 1477768023989,
|
|
||||||
"version": 2,
|
|
||||||
"responses": [],
|
|
||||||
"tests": null,
|
|
||||||
"currentHelper": "normal",
|
|
||||||
"helperAttributes": {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "fddfc4fa-5114-69e3-4744-203ed71a526b",
|
|
||||||
"headers": "",
|
|
||||||
"url": "http://localhost:5000/posts/1",
|
|
||||||
"pathVariables": {},
|
|
||||||
"preRequestScript": null,
|
|
||||||
"method": "PUT",
|
|
||||||
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375",
|
|
||||||
"data": [],
|
|
||||||
"dataMode": "raw",
|
|
||||||
"name": "PUT http://localhost:5000/posts/1",
|
|
||||||
"description": "",
|
|
||||||
"descriptionFormat": "html",
|
|
||||||
"time": 1477768307036,
|
|
||||||
"version": 2,
|
|
||||||
"responses": [],
|
|
||||||
"tests": null,
|
"tests": null,
|
||||||
"currentHelper": "normal",
|
"currentHelper": "normal",
|
||||||
"helperAttributes": {},
|
"helperAttributes": {},
|
||||||
"rawModeData": "{\n \"userId\": 1,\n \"title\": \"test\",\n \"body\": \"test\"\n}"
|
"time": 1508849923518,
|
||||||
|
"name": "GET http://localhost:5000/admin/.well-known/openid-configuration",
|
||||||
|
"description": "",
|
||||||
|
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375",
|
||||||
|
"responses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"folder": null,
|
||||||
|
"id": "a1c95935-ed18-d5dc-bcb8-a3db8ba1934f",
|
||||||
|
"name": "GET http://localhost:5000/posts",
|
||||||
|
"dataMode": "params",
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"key": "client_id",
|
||||||
|
"value": "admin",
|
||||||
|
"type": "text",
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "client_secret",
|
||||||
|
"value": "secret",
|
||||||
|
"type": "text",
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "scope",
|
||||||
|
"value": "admin",
|
||||||
|
"type": "text",
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "username",
|
||||||
|
"value": "admin",
|
||||||
|
"type": "text",
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "password",
|
||||||
|
"value": "admin",
|
||||||
|
"type": "text",
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "grant_type",
|
||||||
|
"value": "password",
|
||||||
|
"type": "text",
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rawModeData": null,
|
||||||
|
"descriptionFormat": "html",
|
||||||
|
"description": "",
|
||||||
|
"headers": "",
|
||||||
|
"method": "POST",
|
||||||
|
"pathVariables": {},
|
||||||
|
"url": "http://localhost:5000/admin/configuration",
|
||||||
|
"preRequestScript": null,
|
||||||
|
"tests": null,
|
||||||
|
"currentHelper": "normal",
|
||||||
|
"helperAttributes": "{}",
|
||||||
|
"queryParams": [],
|
||||||
|
"headerData": [],
|
||||||
|
"pathVariableData": [],
|
||||||
|
"responses": [],
|
||||||
|
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"folder": null,
|
||||||
|
"id": "c4494401-3985-a5bf-71fb-6e4171384ac6",
|
||||||
|
"name": "GET http://localhost:5000/posts/1/comments",
|
||||||
|
"dataMode": "params",
|
||||||
|
"data": null,
|
||||||
|
"rawModeData": null,
|
||||||
|
"descriptionFormat": "html",
|
||||||
|
"description": "",
|
||||||
|
"headers": "",
|
||||||
|
"method": "GET",
|
||||||
|
"pathVariables": {},
|
||||||
|
"url": "http://localhost:5000/posts/1/comments",
|
||||||
|
"preRequestScript": null,
|
||||||
|
"tests": null,
|
||||||
|
"currentHelper": "normal",
|
||||||
|
"helperAttributes": "{}",
|
||||||
|
"queryParams": [],
|
||||||
|
"headerData": [],
|
||||||
|
"pathVariableData": [],
|
||||||
|
"responses": [],
|
||||||
|
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"folder": null,
|
||||||
|
"id": "c45d30d7-d9c4-fa05-8110-d6e769bb6ff9",
|
||||||
|
"name": "PATCH http://localhost:5000/posts/1",
|
||||||
|
"dataMode": "raw",
|
||||||
|
"data": [],
|
||||||
|
"rawModeData": "{\n \"title\": \"gfdgsgsdgsdfgsdfgdfg\",\n}",
|
||||||
|
"descriptionFormat": "html",
|
||||||
|
"description": "",
|
||||||
|
"headers": "",
|
||||||
|
"method": "PATCH",
|
||||||
|
"pathVariables": {},
|
||||||
|
"url": "http://localhost:5000/posts/1",
|
||||||
|
"preRequestScript": null,
|
||||||
|
"tests": null,
|
||||||
|
"currentHelper": "normal",
|
||||||
|
"helperAttributes": "{}",
|
||||||
|
"queryParams": [],
|
||||||
|
"headerData": [],
|
||||||
|
"pathVariableData": [],
|
||||||
|
"responses": [],
|
||||||
|
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"folder": null,
|
||||||
|
"id": "e8825dc3-4137-99a7-0000-ef5786610dc3",
|
||||||
|
"name": "POST http://localhost:5000/posts/1",
|
||||||
|
"dataMode": "raw",
|
||||||
|
"data": [],
|
||||||
|
"rawModeData": "{\n \"userId\": 1,\n \"title\": \"test\",\n \"body\": \"test\"\n}",
|
||||||
|
"descriptionFormat": "html",
|
||||||
|
"description": "",
|
||||||
|
"headers": "",
|
||||||
|
"method": "POST",
|
||||||
|
"pathVariables": {},
|
||||||
|
"url": "http://localhost:5000/posts",
|
||||||
|
"preRequestScript": null,
|
||||||
|
"tests": null,
|
||||||
|
"currentHelper": "normal",
|
||||||
|
"helperAttributes": "{}",
|
||||||
|
"queryParams": [],
|
||||||
|
"headerData": [],
|
||||||
|
"pathVariableData": [],
|
||||||
|
"responses": [],
|
||||||
|
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"folder": null,
|
||||||
|
"id": "ea0ed57a-2cb9-8acc-47dd-006b8db2f1b2",
|
||||||
|
"name": "GET http://localhost:5000/posts/1",
|
||||||
|
"dataMode": "params",
|
||||||
|
"data": null,
|
||||||
|
"rawModeData": null,
|
||||||
|
"descriptionFormat": "html",
|
||||||
|
"description": "",
|
||||||
|
"headers": "",
|
||||||
|
"method": "GET",
|
||||||
|
"pathVariables": {},
|
||||||
|
"url": "http://localhost:5000/posts/1",
|
||||||
|
"preRequestScript": null,
|
||||||
|
"tests": null,
|
||||||
|
"currentHelper": "normal",
|
||||||
|
"helperAttributes": "{}",
|
||||||
|
"queryParams": [],
|
||||||
|
"headerData": [],
|
||||||
|
"pathVariableData": [],
|
||||||
|
"responses": [],
|
||||||
|
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"folder": null,
|
||||||
|
"id": "fddfc4fa-5114-69e3-4744-203ed71a526b",
|
||||||
|
"name": "PUT http://localhost:5000/posts/1",
|
||||||
|
"dataMode": "raw",
|
||||||
|
"data": [],
|
||||||
|
"rawModeData": "{\n \"userId\": 1,\n \"title\": \"test\",\n \"body\": \"test\"\n}",
|
||||||
|
"descriptionFormat": "html",
|
||||||
|
"description": "",
|
||||||
|
"headers": "",
|
||||||
|
"method": "PUT",
|
||||||
|
"pathVariables": {},
|
||||||
|
"url": "http://localhost:5000/posts/1",
|
||||||
|
"preRequestScript": null,
|
||||||
|
"tests": null,
|
||||||
|
"currentHelper": "normal",
|
||||||
|
"helperAttributes": "{}",
|
||||||
|
"queryParams": [],
|
||||||
|
"headerData": [],
|
||||||
|
"pathVariableData": [],
|
||||||
|
"responses": [],
|
||||||
|
"collectionId": "4dbde9fe-89f5-be35-bb9f-d3b438e16375"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -9,17 +9,14 @@ namespace Ocelot.ManualTest
|
|||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
IWebHostBuilder builder = new WebHostBuilder();
|
IWebHostBuilder builder = new WebHostBuilder();
|
||||||
|
|
||||||
builder.ConfigureServices(s => {
|
builder.ConfigureServices(s => {
|
||||||
s.AddSingleton(builder);
|
s.AddSingleton(builder);
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.UseKestrel()
|
builder.UseKestrel()
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.UseIISIntegration()
|
||||||
.UseStartup<Startup>();
|
.UseStartup<Startup>();
|
||||||
|
|
||||||
var host = builder.Build();
|
var host = builder.Build();
|
||||||
|
|
||||||
host.Run();
|
host.Run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,13 @@ namespace Ocelot.ManualTest
|
|||||||
.WithDictionaryHandle();
|
.WithDictionaryHandle();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.AddAuthentication()
|
||||||
|
.AddJwtBearer("TestKey", x =>
|
||||||
|
{
|
||||||
|
x.Authority = "test";
|
||||||
|
x.Audience = "test";
|
||||||
|
});
|
||||||
|
|
||||||
services.AddOcelot(Configuration, settings);
|
services.AddOcelot(Configuration, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,17 +13,11 @@
|
|||||||
"TimeoutValue": 5000
|
"TimeoutValue": 5000
|
||||||
},
|
},
|
||||||
"AuthenticationOptions": {
|
"AuthenticationOptions": {
|
||||||
"Provider": "IdentityServer",
|
"AuthenticationProviderKey": "TestKey",
|
||||||
"AllowedScopes": [
|
"AllowedScopes": [
|
||||||
"openid",
|
"openid",
|
||||||
"offline_access"
|
"offline_access"
|
||||||
],
|
]
|
||||||
"IdentityServerConfig": {
|
|
||||||
"ProviderRootUrl": "http://localhost:52888",
|
|
||||||
"ApiName": "api",
|
|
||||||
"ApiSecret": "secret",
|
|
||||||
"RequireHttps": false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"AddHeadersToRequest": {
|
"AddHeadersToRequest": {
|
||||||
"CustomerId": "Claims[CustomerId] > value",
|
"CustomerId": "Claims[CustomerId] > value",
|
||||||
@ -312,6 +306,6 @@
|
|||||||
|
|
||||||
"GlobalConfiguration": {
|
"GlobalConfiguration": {
|
||||||
"RequestIdKey": "OcRequestId",
|
"RequestIdKey": "OcRequestId",
|
||||||
"AdministrationPath": "/admin"
|
"AdministrationPath": "/administration"
|
||||||
}
|
}
|
||||||
}
|
}
|
BIN
test/Ocelot.ManualTest/idsrv3test.pfx
Normal file
BIN
test/Ocelot.ManualTest/idsrv3test.pfx
Normal file
Binary file not shown.
1
test/Ocelot.ManualTest/tempkey.rsa
Normal file
1
test/Ocelot.ManualTest/tempkey.rsa
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"KeyId":"6aad821b3e366a0189ea6c9741eae6ba","Parameters":{"D":"RcfIF/iJ8qnKpHlaJCa9Qz+iN9Z655mfW0B/CycZx0WDQwQtjYNF+ijEkqfpGC3TJ9n19vXHdDEGfONxHwTtgS6PP/VIYYmql7OfCn+tkZUvMeIXykfEXFoNoWJXlT3eMI1JWyZpT/dZJLtmdeY09csDU/LjXTlyFrljW361T0NR/azAHqEfeuoKhqaJ2klzTzjif4xO5kMcTBHVyxrZm0+cbowsKPjI1QRh5xXsst8EDrM7rXStz4enneNaNbvP1nmWx++F7zn+5/WBDcPJVnL1HiyAzMAHj+oXG2JwDizO4RJxLbvQa2Y2jzoDp/qc++s2HWFo1PmuUnOzNIQjyQ==","DP":"x3VwsILF1yo8puLB6TOcb4hMWngz8rqjBl3dty4E3Un7UexVh+NkqTiSXWZNern6Ka6gE8CpdDXhQiYCFbcnBiSF6FVSpjpQ+Qf9PeRj5HipJF+DzGyEOTzwOiBjb6s5CvPUQWvJiqQoP1D+1V+X/+C0zug8+Df73UyHA7uieKc=","DQ":"aaZu9GfgKqUiy0uwPkmnLcwIEDqRlLG14c23OOoEqNRHK9T3OwUKEJ1qK0mbMKIVTwklyiC7uZHqMijIqk0LovTL4nI3LRlDkRjhUsIuubZZOAw7sYYemBUl+wEB/VZofaJ7H/CYtCUXyJhND2DFbTjzgeg3uWoMpyMDHuH/9Pc=","Exponent":"AQAB","InverseQ":"YRV4QA6rwB9BEHjzh5Wk3TcSS1CrwJWVopj/qC1amXxhtM3aMb4ZfKk7XoynLqHyQ86rB2p7dPNP2GL+fIWbt4h/ESO9JqOlM/bVXpdyCvIwchAL82hfHb4FRv+V+J2cksaIA+bHt7ye9n/XSmSr8v0WsjxN2qHzdla3t+J0c1I=","Modulus":"xLJZzQyYbJAqymvvJeig9H4cfXEy3t0KVnRuUumdSBzU/3F7q1vCDBkXLqs8icEv9ZL4MUgDzzSjjYJpVXzvC24L1My3NLhSSZOCGrhSHCx98+cAgrb71tirXXsiBMXKeGhnJ05KopHtPRJVxBvd3d3Kee957y86g1Sbho1XxwWsrzVu5E7YZS+NkJycHkiUseMKeQ+tMLbPoFZPu5EqrrsSWuDjb7XNUjJViyGaOtvL2SQ9QtvDu006fe4m0VVw71ycSt2ReAmlA+EgCFsyLYBIoAhlk7k+lKyYO3a/8E0bzltB6MGaRaGJMB0C9pSxAfGSmSpIi2OUy0YIpIoDoQ==","P":"ydx6DVoXf3DgS6WZtrR82xNf12kLD5cGUToPwwIjjX5oQywOhGXOV4GCrqISDff2bosrPvleBfuJ5KH9KRVAaEjh1At554Bq+Nw8cc/1mTXEOSKENDtA9GjkpthR0QW1FDFRR5Tc8sRuoBpulN1rJIDIkfEkqwlpugFmk2UrDk8=","Q":"+XNIV8qMorQ11C1fVj4L91wufF4NqVqCdm/PN3f+xZ5UWoiCOil+njRuIL09ZifEwy3fgqD06Fu/SvaqMODyKAzA+RMUJU0sk92aOzAhKiGBk38sEvEuDUKZYNJm5NLjo9XXBG8DQzSUPvmIFLaMCloA95Ozie0mJcrXcimCww8="}}
|
@ -1,100 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Moq;
|
|
||||||
using Ocelot.Authentication.Handler;
|
|
||||||
using Ocelot.Authentication.Handler.Creator;
|
|
||||||
using Ocelot.Authentication.Handler.Factory;
|
|
||||||
using Ocelot.Configuration.Builder;
|
|
||||||
using Ocelot.Errors;
|
|
||||||
using Ocelot.Responses;
|
|
||||||
using Shouldly;
|
|
||||||
using TestStack.BDDfy;
|
|
||||||
using Xunit;
|
|
||||||
using AuthenticationOptions = Ocelot.Configuration.AuthenticationOptions;
|
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.Authentication
|
|
||||||
{
|
|
||||||
public class AuthenticationHandlerFactoryTests
|
|
||||||
{
|
|
||||||
private readonly IAuthenticationHandlerFactory _authenticationHandlerFactory;
|
|
||||||
private readonly Mock<IApplicationBuilder> _app;
|
|
||||||
private readonly Mock<IAuthenticationHandlerCreator> _creator;
|
|
||||||
private AuthenticationOptions _authenticationOptions;
|
|
||||||
private Response<AuthenticationHandler> _result;
|
|
||||||
|
|
||||||
public AuthenticationHandlerFactoryTests()
|
|
||||||
{
|
|
||||||
_app = new Mock<IApplicationBuilder>();
|
|
||||||
_creator = new Mock<IAuthenticationHandlerCreator>();
|
|
||||||
_authenticationHandlerFactory = new AuthenticationHandlerFactory(_creator.Object);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData("IdentityServer")]
|
|
||||||
[InlineData("Jwt")]
|
|
||||||
public void should_return_access_token_handler(string provider)
|
|
||||||
{
|
|
||||||
var authenticationOptions = new AuthenticationOptionsBuilder()
|
|
||||||
.WithProvider(provider)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
this.Given(x => x.GivenTheAuthenticationOptionsAre(authenticationOptions))
|
|
||||||
.And(x => x.GivenTheCreatorReturns())
|
|
||||||
.When(x => x.WhenIGetFromTheFactory())
|
|
||||||
.Then(x => x.ThenTheHandlerIsReturned(provider))
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_return_error_if_cannot_create_handler()
|
|
||||||
{
|
|
||||||
var authenticationOptions = new AuthenticationOptionsBuilder()
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
this.Given(x => x.GivenTheAuthenticationOptionsAre(authenticationOptions))
|
|
||||||
.And(x => x.GivenTheCreatorReturnsAnError())
|
|
||||||
.When(x => x.WhenIGetFromTheFactory())
|
|
||||||
.Then(x => x.ThenAnErrorResponseIsReturned())
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenTheAuthenticationOptionsAre(AuthenticationOptions authenticationOptions)
|
|
||||||
{
|
|
||||||
_authenticationOptions = authenticationOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenTheCreatorReturnsAnError()
|
|
||||||
{
|
|
||||||
_creator
|
|
||||||
.Setup(x => x.Create(It.IsAny<IApplicationBuilder>(), It.IsAny<AuthenticationOptions>()))
|
|
||||||
.Returns(new ErrorResponse<RequestDelegate>(new List<Error>
|
|
||||||
{
|
|
||||||
new UnableToCreateAuthenticationHandlerError($"Unable to create authentication handler for xxx")
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenTheCreatorReturns()
|
|
||||||
{
|
|
||||||
_creator
|
|
||||||
.Setup(x => x.Create(It.IsAny<IApplicationBuilder>(), It.IsAny<AuthenticationOptions>()))
|
|
||||||
.Returns(new OkResponse<RequestDelegate>(x => Task.CompletedTask));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WhenIGetFromTheFactory()
|
|
||||||
{
|
|
||||||
_result = _authenticationHandlerFactory.Get(_app.Object, _authenticationOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThenTheHandlerIsReturned(string expected)
|
|
||||||
{
|
|
||||||
_result.Data.Provider.ShouldBe(expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThenAnErrorResponseIsReturned()
|
|
||||||
{
|
|
||||||
_result.IsError.ShouldBeTrue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,11 +2,9 @@
|
|||||||
{
|
{
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Ocelot.Authentication.Handler.Factory;
|
|
||||||
using Ocelot.Authentication.Middleware;
|
using Ocelot.Authentication.Middleware;
|
||||||
using Ocelot.Configuration.Builder;
|
using Ocelot.Configuration.Builder;
|
||||||
using Ocelot.DownstreamRouteFinder;
|
using Ocelot.DownstreamRouteFinder;
|
||||||
@ -19,13 +17,10 @@
|
|||||||
|
|
||||||
public class AuthenticationMiddlewareTests : ServerHostedMiddlewareTest
|
public class AuthenticationMiddlewareTests : ServerHostedMiddlewareTest
|
||||||
{
|
{
|
||||||
private readonly Mock<IAuthenticationHandlerFactory> _authFactory;
|
|
||||||
private OkResponse<DownstreamRoute> _downstreamRoute;
|
private OkResponse<DownstreamRoute> _downstreamRoute;
|
||||||
|
|
||||||
public AuthenticationMiddlewareTests()
|
public AuthenticationMiddlewareTests()
|
||||||
{
|
{
|
||||||
_authFactory = new Mock<IAuthenticationHandlerFactory>();
|
|
||||||
|
|
||||||
GivenTheTestServerIsConfigured();
|
GivenTheTestServerIsConfigured();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +40,6 @@
|
|||||||
{
|
{
|
||||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||||
services.AddLogging();
|
services.AddLogging();
|
||||||
services.AddSingleton(_authFactory.Object);
|
|
||||||
services.AddSingleton(ScopedRepository.Object);
|
services.AddSingleton(ScopedRepository.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,133 +1,133 @@
|
|||||||
using System.Collections.Generic;
|
// using System.Collections.Generic;
|
||||||
using Ocelot.Configuration;
|
// using Ocelot.Configuration;
|
||||||
using Ocelot.Configuration.Builder;
|
// using Ocelot.Configuration.Builder;
|
||||||
using Ocelot.Configuration.Creator;
|
// using Ocelot.Configuration.Creator;
|
||||||
using Ocelot.Configuration.File;
|
// using Ocelot.Configuration.File;
|
||||||
using Shouldly;
|
// using Shouldly;
|
||||||
using TestStack.BDDfy;
|
// using TestStack.BDDfy;
|
||||||
using Xunit;
|
// using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.Configuration
|
// namespace Ocelot.UnitTests.Configuration
|
||||||
{
|
// {
|
||||||
public class AuthenticationOptionsCreatorTests
|
// public class AuthenticationOptionsCreatorTests
|
||||||
{
|
// {
|
||||||
private readonly AuthenticationOptionsCreator _authOptionsCreator;
|
// private readonly AuthenticationOptionsCreator _authOptionsCreator;
|
||||||
private FileReRoute _fileReRoute;
|
// private FileReRoute _fileReRoute;
|
||||||
private AuthenticationOptions _result;
|
// private AuthenticationOptions _result;
|
||||||
|
|
||||||
public AuthenticationOptionsCreatorTests()
|
// public AuthenticationOptionsCreatorTests()
|
||||||
{
|
// {
|
||||||
_authOptionsCreator = new AuthenticationOptionsCreator(new AuthenticationProviderConfigCreator());
|
// _authOptionsCreator = new AuthenticationOptionsCreator(new AuthenticationProviderConfigCreator());
|
||||||
}
|
// }
|
||||||
|
|
||||||
[Fact]
|
// [Fact]
|
||||||
public void should_return_auth_options()
|
// public void should_return_auth_options()
|
||||||
{
|
// {
|
||||||
var fileReRoute = new FileReRoute()
|
// var fileReRoute = new FileReRoute()
|
||||||
{
|
// {
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
// AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
// {
|
||||||
Provider = "Geoff",
|
// Provider = "Geoff",
|
||||||
IdentityServerConfig = new FileIdentityServerConfig()
|
// IdentityServerConfig = new FileIdentityServerConfig()
|
||||||
{
|
// {
|
||||||
ProviderRootUrl = "http://www.bbc.co.uk/",
|
// ProviderRootUrl = "http://www.bbc.co.uk/",
|
||||||
ApiName = "Laura",
|
// ApiName = "Laura",
|
||||||
RequireHttps = true,
|
// RequireHttps = true,
|
||||||
ApiSecret = "secret"
|
// ApiSecret = "secret"
|
||||||
},
|
// },
|
||||||
AllowedScopes = new List<string> { "cheese" },
|
// AllowedScopes = new List<string> { "cheese" },
|
||||||
|
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
var authenticationConfig = new IdentityServerConfigBuilder()
|
// var authenticationConfig = new IdentityServerConfigBuilder()
|
||||||
.WithProviderRootUrl(fileReRoute.AuthenticationOptions?.IdentityServerConfig?.ProviderRootUrl)
|
// .WithProviderRootUrl(fileReRoute.AuthenticationOptions?.IdentityServerConfig?.ProviderRootUrl)
|
||||||
.WithApiName(fileReRoute.AuthenticationOptions?.IdentityServerConfig?.ApiName)
|
// .WithApiName(fileReRoute.AuthenticationOptions?.IdentityServerConfig?.ApiName)
|
||||||
.WithRequireHttps(fileReRoute.AuthenticationOptions.IdentityServerConfig.RequireHttps)
|
// .WithRequireHttps(fileReRoute.AuthenticationOptions.IdentityServerConfig.RequireHttps)
|
||||||
.WithApiSecret(fileReRoute.AuthenticationOptions?.IdentityServerConfig?.ApiSecret)
|
// .WithApiSecret(fileReRoute.AuthenticationOptions?.IdentityServerConfig?.ApiSecret)
|
||||||
.Build();
|
// .Build();
|
||||||
|
|
||||||
var expected = new AuthenticationOptionsBuilder()
|
// var expected = new AuthenticationOptionsBuilder()
|
||||||
.WithProvider(fileReRoute.AuthenticationOptions?.Provider)
|
// .WithProvider(fileReRoute.AuthenticationOptions?.Provider)
|
||||||
.WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
|
// .WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
|
||||||
.WithConfig(authenticationConfig)
|
// .WithConfig(authenticationConfig)
|
||||||
.Build();
|
// .Build();
|
||||||
|
|
||||||
this.Given(x => x.GivenTheFollowing(fileReRoute))
|
// this.Given(x => x.GivenTheFollowing(fileReRoute))
|
||||||
.When(x => x.WhenICreateTheAuthenticationOptions())
|
// .When(x => x.WhenICreateTheAuthenticationOptions())
|
||||||
.Then(x => x.ThenTheFollowingIdentityServerConfigIsReturned(expected))
|
// .Then(x => x.ThenTheFollowingIdentityServerConfigIsReturned(expected))
|
||||||
.BDDfy();
|
// .BDDfy();
|
||||||
}
|
// }
|
||||||
|
|
||||||
[Fact]
|
// [Fact]
|
||||||
public void should_return_Jwt_auth_options()
|
// public void should_return_Jwt_auth_options()
|
||||||
{
|
// {
|
||||||
var fileReRoute = new FileReRoute()
|
// var fileReRoute = new FileReRoute()
|
||||||
{
|
// {
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
// AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
// {
|
||||||
Provider = "Jwt",
|
// Provider = "Jwt",
|
||||||
JwtConfig = new FileJwtConfig()
|
// JwtConfig = new FileJwtConfig()
|
||||||
{
|
// {
|
||||||
Audience = "Audience",
|
// Audience = "Audience",
|
||||||
Authority = "Authority"
|
// Authority = "Authority"
|
||||||
},
|
// },
|
||||||
AllowedScopes = new List<string> { "cheese" }
|
// AllowedScopes = new List<string> { "cheese" }
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
var authenticationConfig = new JwtConfigBuilder()
|
// var authenticationConfig = new JwtConfigBuilder()
|
||||||
.WithAudience(fileReRoute.AuthenticationOptions?.JwtConfig?.Audience)
|
// .WithAudience(fileReRoute.AuthenticationOptions?.JwtConfig?.Audience)
|
||||||
.WithAuthority(fileReRoute.AuthenticationOptions?.JwtConfig?.Authority)
|
// .WithAuthority(fileReRoute.AuthenticationOptions?.JwtConfig?.Authority)
|
||||||
.Build();
|
// .Build();
|
||||||
|
|
||||||
var expected = new AuthenticationOptionsBuilder()
|
// var expected = new AuthenticationOptionsBuilder()
|
||||||
.WithProvider(fileReRoute.AuthenticationOptions?.Provider)
|
// .WithProvider(fileReRoute.AuthenticationOptions?.Provider)
|
||||||
.WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
|
// .WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
|
||||||
.WithConfig(authenticationConfig)
|
// .WithConfig(authenticationConfig)
|
||||||
.Build();
|
// .Build();
|
||||||
|
|
||||||
this.Given(x => x.GivenTheFollowing(fileReRoute))
|
// this.Given(x => x.GivenTheFollowing(fileReRoute))
|
||||||
.When(x => x.WhenICreateTheAuthenticationOptions())
|
// .When(x => x.WhenICreateTheAuthenticationOptions())
|
||||||
.Then(x => x.ThenTheFollowingJwtConfigIsReturned(expected))
|
// .Then(x => x.ThenTheFollowingJwtConfigIsReturned(expected))
|
||||||
.BDDfy();
|
// .BDDfy();
|
||||||
}
|
// }
|
||||||
|
|
||||||
private void GivenTheFollowing(FileReRoute fileReRoute)
|
// private void GivenTheFollowing(FileReRoute fileReRoute)
|
||||||
{
|
// {
|
||||||
_fileReRoute = fileReRoute;
|
// _fileReRoute = fileReRoute;
|
||||||
}
|
// }
|
||||||
|
|
||||||
private void WhenICreateTheAuthenticationOptions()
|
// private void WhenICreateTheAuthenticationOptions()
|
||||||
{
|
// {
|
||||||
_result = _authOptionsCreator.Create(_fileReRoute);
|
// _result = _authOptionsCreator.Create(_fileReRoute);
|
||||||
}
|
// }
|
||||||
|
|
||||||
private void ThenTheFollowingJwtConfigIsReturned(AuthenticationOptions expected)
|
// private void ThenTheFollowingJwtConfigIsReturned(AuthenticationOptions expected)
|
||||||
{
|
// {
|
||||||
_result.AllowedScopes.ShouldBe(expected.AllowedScopes);
|
// _result.AllowedScopes.ShouldBe(expected.AllowedScopes);
|
||||||
_result.Provider.ShouldBe(expected.Provider);
|
// _result.Provider.ShouldBe(expected.Provider);
|
||||||
|
|
||||||
var _resultSettings = _result.Config as JwtConfig;
|
// var _resultSettings = _result.Config as JwtConfig;
|
||||||
var expectedSettngs = expected.Config as JwtConfig;
|
// var expectedSettngs = expected.Config as JwtConfig;
|
||||||
|
|
||||||
_resultSettings.Audience.ShouldBe(expectedSettngs.Audience);
|
// _resultSettings.Audience.ShouldBe(expectedSettngs.Audience);
|
||||||
_resultSettings.Authority.ShouldBe(expectedSettngs.Authority);
|
// _resultSettings.Authority.ShouldBe(expectedSettngs.Authority);
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
private void ThenTheFollowingIdentityServerConfigIsReturned(AuthenticationOptions expected)
|
// private void ThenTheFollowingIdentityServerConfigIsReturned(AuthenticationOptions expected)
|
||||||
{
|
// {
|
||||||
_result.AllowedScopes.ShouldBe(expected.AllowedScopes);
|
// _result.AllowedScopes.ShouldBe(expected.AllowedScopes);
|
||||||
_result.Provider.ShouldBe(expected.Provider);
|
// _result.Provider.ShouldBe(expected.Provider);
|
||||||
|
|
||||||
var _resultSettings = _result.Config as IdentityServerConfig;
|
// var _resultSettings = _result.Config as IdentityServerConfig;
|
||||||
var expectedSettngs = expected.Config as IdentityServerConfig;
|
// var expectedSettngs = expected.Config as IdentityServerConfig;
|
||||||
|
|
||||||
_resultSettings.ProviderRootUrl.ShouldBe(expectedSettngs.ProviderRootUrl);
|
// _resultSettings.ProviderRootUrl.ShouldBe(expectedSettngs.ProviderRootUrl);
|
||||||
_resultSettings.RequireHttps.ShouldBe(expectedSettngs.RequireHttps);
|
// _resultSettings.RequireHttps.ShouldBe(expectedSettngs.RequireHttps);
|
||||||
_resultSettings.ApiName.ShouldBe(expectedSettngs.ApiName);
|
// _resultSettings.ApiName.ShouldBe(expectedSettngs.ApiName);
|
||||||
_resultSettings.ApiSecret.ShouldBe(expectedSettngs.ApiSecret);
|
// _resultSettings.ApiSecret.ShouldBe(expectedSettngs.ApiSecret);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
@ -1,4 +1,11 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Moq;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Configuration.Validator;
|
using Ocelot.Configuration.Validator;
|
||||||
using Ocelot.Responses;
|
using Ocelot.Responses;
|
||||||
@ -13,10 +20,12 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
private readonly IConfigurationValidator _configurationValidator;
|
private readonly IConfigurationValidator _configurationValidator;
|
||||||
private FileConfiguration _fileConfiguration;
|
private FileConfiguration _fileConfiguration;
|
||||||
private Response<ConfigurationValidationResult> _result;
|
private Response<ConfigurationValidationResult> _result;
|
||||||
|
private Mock<IAuthenticationSchemeProvider> _provider;
|
||||||
|
|
||||||
public ConfigurationValidationTests()
|
public ConfigurationValidationTests()
|
||||||
{
|
{
|
||||||
_configurationValidator = new FileConfigurationValidator();
|
_provider = new Mock<IAuthenticationSchemeProvider>();
|
||||||
|
_configurationValidator = new FileConfigurationValidator(_provider.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -48,7 +57,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = "/api/products/",
|
DownstreamPathTemplate = "/api/products/",
|
||||||
UpstreamPathTemplate = "http://asdf.com"
|
UpstreamPathTemplate = "/asdf/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@ -57,6 +66,44 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void configuration_is_invalid_without_slash_prefix_downstream_path_template()
|
||||||
|
{
|
||||||
|
this.Given(x => x.GivenAConfiguration(new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "api/products/",
|
||||||
|
UpstreamPathTemplate = "/asdf/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.When(x => x.WhenIValidateTheConfiguration())
|
||||||
|
.Then(x => x.ThenTheResultIsNotValid())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void configuration_is_invalid_without_slash_prefix_upstream_path_template()
|
||||||
|
{
|
||||||
|
this.Given(x => x.GivenAConfiguration(new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/api/products/",
|
||||||
|
UpstreamPathTemplate = "api/prod/",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.When(x => x.WhenIValidateTheConfiguration())
|
||||||
|
.Then(x => x.ThenTheResultIsNotValid())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void configuration_is_valid_with_valid_authentication_provider()
|
public void configuration_is_valid_with_valid_authentication_provider()
|
||||||
{
|
{
|
||||||
@ -67,14 +114,15 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = "/api/products/",
|
DownstreamPathTemplate = "/api/products/",
|
||||||
UpstreamPathTemplate = "http://asdf.com",
|
UpstreamPathTemplate = "/asdf/",
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions()
|
||||||
{
|
{
|
||||||
Provider = "IdentityServer"
|
AuthenticationProviderKey = "Test"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
.And(x => x.GivenTheAuthSchemeExists("Test"))
|
||||||
.When(x => x.WhenIValidateTheConfiguration())
|
.When(x => x.WhenIValidateTheConfiguration())
|
||||||
.Then(x => x.ThenTheResultIsValid())
|
.Then(x => x.ThenTheResultIsValid())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -90,12 +138,11 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = "/api/products/",
|
DownstreamPathTemplate = "/api/products/",
|
||||||
UpstreamPathTemplate = "http://asdf.com",
|
UpstreamPathTemplate = "/asdf/",
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions()
|
||||||
{
|
{
|
||||||
Provider = "BootyBootyBottyRockinEverywhere"
|
AuthenticationProviderKey = "Test"
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.When(x => x.WhenIValidateTheConfiguration())
|
.When(x => x.WhenIValidateTheConfiguration())
|
||||||
@ -114,12 +161,12 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = "/api/products/",
|
DownstreamPathTemplate = "/api/products/",
|
||||||
UpstreamPathTemplate = "http://asdf.com"
|
UpstreamPathTemplate = "/asdf/"
|
||||||
},
|
},
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = "http://www.bbc.co.uk",
|
DownstreamPathTemplate = "http://www.bbc.co.uk",
|
||||||
UpstreamPathTemplate = "http://asdf.com"
|
UpstreamPathTemplate = "/asdf/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@ -136,7 +183,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
private void WhenIValidateTheConfiguration()
|
private void WhenIValidateTheConfiguration()
|
||||||
{
|
{
|
||||||
_result = _configurationValidator.IsValid(_fileConfiguration);
|
_result = _configurationValidator.IsValid(_fileConfiguration).Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenTheResultIsValid()
|
private void ThenTheResultIsValid()
|
||||||
@ -153,5 +200,31 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
{
|
{
|
||||||
_result.Data.Errors[0].ShouldBeOfType<T>();
|
_result.Data.Errors[0].ShouldBeOfType<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void GivenTheAuthSchemeExists(string name)
|
||||||
|
{
|
||||||
|
_provider.Setup(x => x.GetAllSchemesAsync()).ReturnsAsync(new List<AuthenticationScheme>
|
||||||
|
{
|
||||||
|
new AuthenticationScheme(name, name, typeof(TestHandler))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestOptions : AuthenticationSchemeOptions
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestHandler : AuthenticationHandler<TestOptions>
|
||||||
|
{
|
||||||
|
public TestHandler(IOptionsMonitor<TestOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||||
|
{
|
||||||
|
var principal = new ClaimsPrincipal();
|
||||||
|
return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(principal, new AuthenticationProperties(), Scheme.Name)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -45,6 +45,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
private Mock<IReRouteOptionsCreator> _fileReRouteOptionsCreator;
|
private Mock<IReRouteOptionsCreator> _fileReRouteOptionsCreator;
|
||||||
private Mock<IRateLimitOptionsCreator> _rateLimitOptions;
|
private Mock<IRateLimitOptionsCreator> _rateLimitOptions;
|
||||||
private Mock<IRegionCreator> _regionCreator;
|
private Mock<IRegionCreator> _regionCreator;
|
||||||
|
private Mock<IHttpHandlerOptionsCreator> _httpHandlerOptionsCreator;
|
||||||
|
|
||||||
public FileConfigurationCreatorTests()
|
public FileConfigurationCreatorTests()
|
||||||
{
|
{
|
||||||
@ -66,6 +67,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
_fileReRouteOptionsCreator = new Mock<IReRouteOptionsCreator>();
|
_fileReRouteOptionsCreator = new Mock<IReRouteOptionsCreator>();
|
||||||
_rateLimitOptions = new Mock<IRateLimitOptionsCreator>();
|
_rateLimitOptions = new Mock<IRateLimitOptionsCreator>();
|
||||||
_regionCreator = new Mock<IRegionCreator>();
|
_regionCreator = new Mock<IRegionCreator>();
|
||||||
|
_httpHandlerOptionsCreator = new Mock<IHttpHandlerOptionsCreator>();
|
||||||
|
|
||||||
_ocelotConfigurationCreator = new FileOcelotConfigurationCreator(
|
_ocelotConfigurationCreator = new FileOcelotConfigurationCreator(
|
||||||
_fileConfig.Object, _validator.Object, _logger.Object,
|
_fileConfig.Object, _validator.Object, _logger.Object,
|
||||||
@ -73,7 +75,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
_qosProviderFactory.Object, _qosProviderHouse.Object, _claimsToThingCreator.Object,
|
_qosProviderFactory.Object, _qosProviderHouse.Object, _claimsToThingCreator.Object,
|
||||||
_authOptionsCreator.Object, _upstreamTemplatePatternCreator.Object, _requestIdKeyCreator.Object,
|
_authOptionsCreator.Object, _upstreamTemplatePatternCreator.Object, _requestIdKeyCreator.Object,
|
||||||
_serviceProviderConfigCreator.Object, _qosOptionsCreator.Object, _fileReRouteOptionsCreator.Object,
|
_serviceProviderConfigCreator.Object, _qosOptionsCreator.Object, _fileReRouteOptionsCreator.Object,
|
||||||
_rateLimitOptions.Object, _regionCreator.Object);
|
_rateLimitOptions.Object, _regionCreator.Object, _httpHandlerOptionsCreator.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -444,18 +446,55 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_call_httpHandler_creator()
|
||||||
|
{
|
||||||
|
var reRouteOptions = new ReRouteOptionsBuilder()
|
||||||
|
.Build();
|
||||||
|
var httpHandlerOptions = new HttpHandlerOptions(true, true);
|
||||||
|
|
||||||
|
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamHost = "127.0.0.1",
|
||||||
|
UpstreamPathTemplate = "/api/products/{productId}",
|
||||||
|
DownstreamPathTemplate = "/products/{productId}",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Get" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
|
||||||
|
.And(x => x.GivenTheConfigIsValid())
|
||||||
|
.And(x => x.GivenTheFollowingHttpHandlerOptionsAreReturned(httpHandlerOptions))
|
||||||
|
.When(x => x.WhenICreateTheConfig())
|
||||||
|
.Then(x => x.ThenTheHttpHandlerOptionsCreatorIsCalledCorrectly())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheFollowingHttpHandlerOptionsAreReturned(HttpHandlerOptions httpHandlerOptions)
|
||||||
|
{
|
||||||
|
_httpHandlerOptionsCreator.Setup(x => x.Create(It.IsAny<FileReRoute>()))
|
||||||
|
.Returns(httpHandlerOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheHttpHandlerOptionsCreatorIsCalledCorrectly()
|
||||||
|
{
|
||||||
|
_httpHandlerOptionsCreator.Verify(x => x.Create(_fileConfiguration.ReRoutes[0]), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(AuthenticationConfigTestData.GetAuthenticationData), MemberType = typeof(AuthenticationConfigTestData))]
|
[MemberData(nameof(AuthenticationConfigTestData.GetAuthenticationData), MemberType = typeof(AuthenticationConfigTestData))]
|
||||||
public void should_create_with_headers_to_extract(string provider, IAuthenticationConfig config, FileConfiguration fileConfig)
|
public void should_create_with_headers_to_extract(FileConfiguration fileConfig)
|
||||||
{
|
{
|
||||||
var reRouteOptions = new ReRouteOptionsBuilder()
|
var reRouteOptions = new ReRouteOptionsBuilder()
|
||||||
.WithIsAuthenticated(true)
|
.WithIsAuthenticated(true)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var authenticationOptions = new AuthenticationOptionsBuilder()
|
var authenticationOptions = new AuthenticationOptionsBuilder()
|
||||||
.WithProvider(provider)
|
|
||||||
.WithAllowedScopes(new List<string>())
|
.WithAllowedScopes(new List<string>())
|
||||||
.WithConfig(config)
|
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var expected = new List<ReRoute>
|
var expected = new List<ReRoute>
|
||||||
@ -480,23 +519,21 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.And(x => x.GivenTheLoadBalancerFactoryReturns())
|
.And(x => x.GivenTheLoadBalancerFactoryReturns())
|
||||||
.When(x => x.WhenICreateTheConfig())
|
.When(x => x.WhenICreateTheConfig())
|
||||||
.Then(x => x.ThenTheReRoutesAre(expected))
|
.Then(x => x.ThenTheReRoutesAre(expected))
|
||||||
.And(x => x.ThenTheAuthenticationOptionsAre(provider, expected))
|
.And(x => x.ThenTheAuthenticationOptionsAre(expected))
|
||||||
.And(x => x.ThenTheAuthOptionsCreatorIsCalledCorrectly())
|
.And(x => x.ThenTheAuthOptionsCreatorIsCalledCorrectly())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(AuthenticationConfigTestData.GetAuthenticationData), MemberType = typeof(AuthenticationConfigTestData))]
|
[MemberData(nameof(AuthenticationConfigTestData.GetAuthenticationData), MemberType = typeof(AuthenticationConfigTestData))]
|
||||||
public void should_create_with_authentication_properties(string provider, IAuthenticationConfig config, FileConfiguration fileConfig)
|
public void should_create_with_authentication_properties(FileConfiguration fileConfig)
|
||||||
{
|
{
|
||||||
var reRouteOptions = new ReRouteOptionsBuilder()
|
var reRouteOptions = new ReRouteOptionsBuilder()
|
||||||
.WithIsAuthenticated(true)
|
.WithIsAuthenticated(true)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var authenticationOptions = new AuthenticationOptionsBuilder()
|
var authenticationOptions = new AuthenticationOptionsBuilder()
|
||||||
.WithProvider(provider)
|
|
||||||
.WithAllowedScopes(new List<string>())
|
.WithAllowedScopes(new List<string>())
|
||||||
.WithConfig(config)
|
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var expected = new List<ReRoute>
|
var expected = new List<ReRoute>
|
||||||
@ -516,7 +553,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.And(x => x.GivenTheLoadBalancerFactoryReturns())
|
.And(x => x.GivenTheLoadBalancerFactoryReturns())
|
||||||
.When(x => x.WhenICreateTheConfig())
|
.When(x => x.WhenICreateTheConfig())
|
||||||
.Then(x => x.ThenTheReRoutesAre(expected))
|
.Then(x => x.ThenTheReRoutesAre(expected))
|
||||||
.And(x => x.ThenTheAuthenticationOptionsAre(provider, expected))
|
.And(x => x.ThenTheAuthenticationOptionsAre(expected))
|
||||||
.And(x => x.ThenTheAuthOptionsCreatorIsCalledCorrectly())
|
.And(x => x.ThenTheAuthOptionsCreatorIsCalledCorrectly())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
@ -538,7 +575,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
{
|
{
|
||||||
_validator
|
_validator
|
||||||
.Setup(x => x.IsValid(It.IsAny<FileConfiguration>()))
|
.Setup(x => x.IsValid(It.IsAny<FileConfiguration>()))
|
||||||
.Returns(new OkResponse<ConfigurationValidationResult>(new ConfigurationValidationResult(false)));
|
.ReturnsAsync(new OkResponse<ConfigurationValidationResult>(new ConfigurationValidationResult(false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenTheConfigIs(FileConfiguration fileConfiguration)
|
private void GivenTheConfigIs(FileConfiguration fileConfiguration)
|
||||||
@ -587,34 +624,13 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenTheAuthenticationOptionsAre(string provider, List<ReRoute> expectedReRoutes)
|
private void ThenTheAuthenticationOptionsAre(List<ReRoute> expectedReRoutes)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _config.Data.ReRoutes.Count; i++)
|
for (int i = 0; i < _config.Data.ReRoutes.Count; i++)
|
||||||
{
|
{
|
||||||
var result = _config.Data.ReRoutes[i].AuthenticationOptions;
|
var result = _config.Data.ReRoutes[i].AuthenticationOptions;
|
||||||
var expected = expectedReRoutes[i].AuthenticationOptions;
|
var expected = expectedReRoutes[i].AuthenticationOptions;
|
||||||
|
|
||||||
result.AllowedScopes.ShouldBe(expected.AllowedScopes);
|
result.AllowedScopes.ShouldBe(expected.AllowedScopes);
|
||||||
result.Provider.ShouldBe(expected.Provider);
|
|
||||||
|
|
||||||
if (provider.ToLower() == "identityserver")
|
|
||||||
{
|
|
||||||
var config = result.Config as IdentityServerConfig;
|
|
||||||
var expectedConfig = expected.Config as IdentityServerConfig;
|
|
||||||
|
|
||||||
config.ProviderRootUrl.ShouldBe(expectedConfig.ProviderRootUrl);
|
|
||||||
config.RequireHttps.ShouldBe(expectedConfig.RequireHttps);
|
|
||||||
config.ApiName.ShouldBe(expectedConfig.ApiName);
|
|
||||||
config.ApiSecret.ShouldBe(expectedConfig.ApiSecret);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var config = result.Config as JwtConfig;
|
|
||||||
var expectedConfig = expected.Config as JwtConfig;
|
|
||||||
|
|
||||||
config.Audience.ShouldBe(expectedConfig.Audience);
|
|
||||||
config.Authority.ShouldBe(expectedConfig.Authority);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
using Ocelot.Configuration;
|
||||||
|
using Ocelot.Configuration.Creator;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
|
using Shouldly;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Ocelot.UnitTests.Configuration
|
||||||
|
{
|
||||||
|
|
||||||
|
public class HttpHandlerOptionsCreatorTests
|
||||||
|
{
|
||||||
|
private readonly IHttpHandlerOptionsCreator _httpHandlerOptionsCreator;
|
||||||
|
private FileReRoute _fileReRoute;
|
||||||
|
private HttpHandlerOptions _httpHandlerOptions;
|
||||||
|
|
||||||
|
public HttpHandlerOptionsCreatorTests()
|
||||||
|
{
|
||||||
|
_httpHandlerOptionsCreator = new HttpHandlerOptionsCreator();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_create_options_with_useCookie_and_allowAutoRedirect_true_as_default()
|
||||||
|
{
|
||||||
|
var fileReRoute = new FileReRoute();
|
||||||
|
var expectedOptions = new HttpHandlerOptions(true, true);
|
||||||
|
|
||||||
|
this.Given(x => GivenTheFollowing(fileReRoute))
|
||||||
|
.When(x => WhenICreateHttpHandlerOptions())
|
||||||
|
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_create_options_with_specified_useCookie_and_allowAutoRedirect()
|
||||||
|
{
|
||||||
|
var fileReRoute = new FileReRoute
|
||||||
|
{
|
||||||
|
HttpHandlerOptions = new FileHttpHandlerOptions
|
||||||
|
{
|
||||||
|
AllowAutoRedirect = false,
|
||||||
|
UseCookieContainer = false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var expectedOptions = new HttpHandlerOptions(false, false);
|
||||||
|
|
||||||
|
this.Given(x => GivenTheFollowing(fileReRoute))
|
||||||
|
.When(x => WhenICreateHttpHandlerOptions())
|
||||||
|
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheFollowing(FileReRoute fileReRoute)
|
||||||
|
{
|
||||||
|
_fileReRoute = fileReRoute;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WhenICreateHttpHandlerOptions()
|
||||||
|
{
|
||||||
|
_httpHandlerOptions = _httpHandlerOptionsCreator.Create(_fileReRoute);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheFollowingOptionsReturned(HttpHandlerOptions options)
|
||||||
|
{
|
||||||
|
_httpHandlerOptions.ShouldNotBeNull();
|
||||||
|
_httpHandlerOptions.AllowAutoRedirect.ShouldBe(options.AllowAutoRedirect);
|
||||||
|
_httpHandlerOptions.UseCookieContainer.ShouldBe(options.UseCookieContainer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -34,9 +34,9 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
ExceptionsAllowedBeforeBreaking = 1,
|
ExceptionsAllowedBeforeBreaking = 1,
|
||||||
TimeoutValue = 1
|
TimeoutValue = 1
|
||||||
},
|
},
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions()
|
||||||
{
|
{
|
||||||
Provider = "IdentityServer"
|
AuthenticationProviderKey = "Test"
|
||||||
},
|
},
|
||||||
RouteClaimsRequirement = new Dictionary<string, string>()
|
RouteClaimsRequirement = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
|
@ -28,7 +28,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("(?i)/PRODUCTS/.*/$"))
|
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS/.*/$"))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
};
|
};
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("/PRODUCTS/.*/$"))
|
.Then(x => x.ThenTheFollowingIsReturned("^/PRODUCTS/.*/$"))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("/api/products/.*/$"))
|
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/.*/$"))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("/api/products/.*/variants/.*/$"))
|
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/.*/variants/.*/$"))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -86,7 +86,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("/api/products/.*/variants/.*/$"))
|
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/.*/variants/.*/$"))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_route()
|
public void should_return_route()
|
||||||
{
|
{
|
||||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher"))
|
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher/"))
|
||||||
.And(x =>x.GivenTheTemplateVariableAndNameFinderReturns(
|
.And(x =>x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||||
new OkResponse<List<UrlPathPlaceholderNameAndValue>>(
|
new OkResponse<List<UrlPathPlaceholderNameAndValue>>(
|
||||||
new List<UrlPathPlaceholderNameAndValue>())))
|
new List<UrlPathPlaceholderNameAndValue>())))
|
||||||
@ -65,6 +65,39 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_append_slash_to_upstream_url_path()
|
||||||
|
{
|
||||||
|
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher"))
|
||||||
|
.And(x =>x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||||
|
new OkResponse<List<UrlPathPlaceholderNameAndValue>>(
|
||||||
|
new List<UrlPathPlaceholderNameAndValue>())))
|
||||||
|
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||||
|
{
|
||||||
|
new ReRouteBuilder()
|
||||||
|
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||||
|
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||||
|
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||||
|
.WithUpstreamTemplatePattern("someUpstreamPath")
|
||||||
|
.Build()
|
||||||
|
}, string.Empty
|
||||||
|
))
|
||||||
|
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||||
|
.And(x => x.GivenTheUpstreamHttpMethodIs("Get"))
|
||||||
|
.When(x => x.WhenICallTheFinder())
|
||||||
|
.Then(
|
||||||
|
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
|
||||||
|
new List<UrlPathPlaceholderNameAndValue>(),
|
||||||
|
new ReRouteBuilder()
|
||||||
|
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||||
|
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||||
|
.Build()
|
||||||
|
)))
|
||||||
|
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly("matchInUrlMatcher/"))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_route_if_upstream_path_and_upstream_template_are_the_same()
|
public void should_return_route_if_upstream_path_and_upstream_template_are_the_same()
|
||||||
{
|
{
|
||||||
@ -137,7 +170,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_not_return_route()
|
public void should_not_return_route()
|
||||||
{
|
{
|
||||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("dontMatchPath"))
|
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("dontMatchPath/"))
|
||||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||||
{
|
{
|
||||||
new ReRouteBuilder()
|
new ReRouteBuilder()
|
||||||
@ -269,6 +302,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
|||||||
.Verify(x => x.Match(_upstreamUrlPath, _reRoutesConfig[0].UpstreamPathTemplate.Value), Times.Once);
|
.Verify(x => x.Match(_upstreamUrlPath, _reRoutesConfig[0].UpstreamPathTemplate.Value), Times.Once);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ThenTheUrlMatcherIsCalledCorrectly(string expectedUpstreamUrlPath)
|
||||||
|
{
|
||||||
|
_mockMatcher
|
||||||
|
.Verify(x => x.Match(expectedUpstreamUrlPath, _reRoutesConfig[0].UpstreamPathTemplate.Value), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
private void ThenTheUrlMatcherIsNotCalled()
|
private void ThenTheUrlMatcherIsNotCalled()
|
||||||
{
|
{
|
||||||
_mockMatcher
|
_mockMatcher
|
||||||
|
@ -28,6 +28,16 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_not_match_issue_134()
|
||||||
|
{
|
||||||
|
this.Given(x => x.GivenIHaveAUpstreamPath("/api/vacancy/1/"))
|
||||||
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)/vacancy/.*/$"))
|
||||||
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.And(x => x.ThenTheResultIsFalse())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_match_forward_slash_only_regex()
|
public void should_match_forward_slash_only_regex()
|
||||||
{
|
{
|
||||||
@ -42,7 +52,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
|||||||
public void should_find_match_when_template_smaller_than_valid_path()
|
public void should_find_match_when_template_smaller_than_valid_path()
|
||||||
{
|
{
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("/api/products/2354325435624623464235"))
|
this.Given(x => x.GivenIHaveAUpstreamPath("/api/products/2354325435624623464235"))
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("/api/products/.*$"))
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/api/products/.*$"))
|
||||||
.When(x => x.WhenIMatchThePaths())
|
.When(x => x.WhenIMatchThePaths())
|
||||||
.And(x => x.ThenTheResultIsTrue())
|
.And(x => x.ThenTheResultIsTrue())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -52,7 +62,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
|||||||
public void should_not_find_match()
|
public void should_not_find_match()
|
||||||
{
|
{
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("/api/values"))
|
this.Given(x => x.GivenIHaveAUpstreamPath("/api/values"))
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("/$"))
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/$"))
|
||||||
.When(x => x.WhenIMatchThePaths())
|
.When(x => x.WhenIMatchThePaths())
|
||||||
.And(x => x.ThenTheResultIsFalse())
|
.And(x => x.ThenTheResultIsFalse())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -62,7 +72,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
|||||||
public void can_match_down_stream_url()
|
public void can_match_down_stream_url()
|
||||||
{
|
{
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath(""))
|
this.Given(x => x.GivenIHaveAUpstreamPath(""))
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("$"))
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^$"))
|
||||||
.When(x => x.WhenIMatchThePaths())
|
.When(x => x.WhenIMatchThePaths())
|
||||||
.And(x => x.ThenTheResultIsTrue())
|
.And(x => x.ThenTheResultIsTrue())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -72,7 +82,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
|||||||
public void can_match_down_stream_url_with_no_slash()
|
public void can_match_down_stream_url_with_no_slash()
|
||||||
{
|
{
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("api"))
|
this.Given(x => x.GivenIHaveAUpstreamPath("api"))
|
||||||
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api$"))
|
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api$"))
|
||||||
.When(x => x.WhenIMatchThePaths())
|
.When(x => x.WhenIMatchThePaths())
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -82,7 +92,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
|||||||
public void can_match_down_stream_url_with_one_slash()
|
public void can_match_down_stream_url_with_one_slash()
|
||||||
{
|
{
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("api/"))
|
this.Given(x => x.GivenIHaveAUpstreamPath("api/"))
|
||||||
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/$"))
|
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/$"))
|
||||||
.When(x => x.WhenIMatchThePaths())
|
.When(x => x.WhenIMatchThePaths())
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -92,7 +102,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
|||||||
public void can_match_down_stream_url_with_downstream_template()
|
public void can_match_down_stream_url_with_downstream_template()
|
||||||
{
|
{
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/"))
|
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/"))
|
||||||
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/$"))
|
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/$"))
|
||||||
.When(x => x.WhenIMatchThePaths())
|
.When(x => x.WhenIMatchThePaths())
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -102,7 +112,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
|||||||
public void can_match_down_stream_url_with_downstream_template_with_one_place_holder()
|
public void can_match_down_stream_url_with_downstream_template_with_one_place_holder()
|
||||||
{
|
{
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1"))
|
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1"))
|
||||||
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*$"))
|
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*$"))
|
||||||
.When(x => x.WhenIMatchThePaths())
|
.When(x => x.WhenIMatchThePaths())
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -112,7 +122,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
|||||||
public void can_match_down_stream_url_with_downstream_template_with_two_place_holders()
|
public void can_match_down_stream_url_with_downstream_template_with_two_place_holders()
|
||||||
{
|
{
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/2"))
|
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/2"))
|
||||||
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*/.*$"))
|
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/.*$"))
|
||||||
.When(x => x.WhenIMatchThePaths())
|
.When(x => x.WhenIMatchThePaths())
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -122,7 +132,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
|||||||
public void can_match_down_stream_url_with_downstream_template_with_two_place_holders_seperated_by_something()
|
public void can_match_down_stream_url_with_downstream_template_with_two_place_holders_seperated_by_something()
|
||||||
{
|
{
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2"))
|
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2"))
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*/categories/.*$"))
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/categories/.*$"))
|
||||||
.When(x => x.WhenIMatchThePaths())
|
.When(x => x.WhenIMatchThePaths())
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -132,7 +142,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
|||||||
public void can_match_down_stream_url_with_downstream_template_with_three_place_holders_seperated_by_something()
|
public void can_match_down_stream_url_with_downstream_template_with_three_place_holders_seperated_by_something()
|
||||||
{
|
{
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/123"))
|
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/123"))
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*/categories/.*/variant/.*$"))
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/categories/.*/variant/.*$"))
|
||||||
.When(x => x.WhenIMatchThePaths())
|
.When(x => x.WhenIMatchThePaths())
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -142,7 +152,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
|||||||
public void can_match_down_stream_url_with_downstream_template_with_three_place_holders()
|
public void can_match_down_stream_url_with_downstream_template_with_three_place_holders()
|
||||||
{
|
{
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/"))
|
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/"))
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*/categories/.*/variant/$"))
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/categories/.*/variant/$"))
|
||||||
.When(x => x.WhenIMatchThePaths())
|
.When(x => x.WhenIMatchThePaths())
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -152,7 +162,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
|||||||
public void should_ignore_case_sensitivity()
|
public void should_ignore_case_sensitivity()
|
||||||
{
|
{
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("API/product/products/1/categories/2/variant/"))
|
this.Given(x => x.GivenIHaveAUpstreamPath("API/product/products/1/categories/2/variant/"))
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("(?i)api/product/products/.*/categories/.*/variant/$"))
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)api/product/products/.*/categories/.*/variant/$"))
|
||||||
.When(x => x.WhenIMatchThePaths())
|
.When(x => x.WhenIMatchThePaths())
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -162,7 +172,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
|||||||
public void should_respect_case_sensitivity()
|
public void should_respect_case_sensitivity()
|
||||||
{
|
{
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("API/product/products/1/categories/2/variant/"))
|
this.Given(x => x.GivenIHaveAUpstreamPath("API/product/products/1/categories/2/variant/"))
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*/categories/.*/variant/$"))
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/categories/.*/variant/$"))
|
||||||
.When(x => x.WhenIMatchThePaths())
|
.When(x => x.WhenIMatchThePaths())
|
||||||
.Then(x => x.ThenTheResultIsFalse())
|
.Then(x => x.ThenTheResultIsFalse())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
|
124
test/Ocelot.UnitTests/Infrastructure/ScopesAuthoriserTests.cs
Normal file
124
test/Ocelot.UnitTests/Infrastructure/ScopesAuthoriserTests.cs
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
using Xunit;
|
||||||
|
using Shouldly;
|
||||||
|
using Ocelot.Authorisation;
|
||||||
|
using Ocelot.Infrastructure.Claims.Parser;
|
||||||
|
using Moq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using Ocelot.Responses;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
using Ocelot.Errors;
|
||||||
|
|
||||||
|
namespace Ocelot.UnitTests.Infrastructure
|
||||||
|
{
|
||||||
|
public class ScopesAuthoriserTests
|
||||||
|
{
|
||||||
|
private ScopesAuthoriser _authoriser;
|
||||||
|
public Mock<IClaimsParser> _parser;
|
||||||
|
private ClaimsPrincipal _principal;
|
||||||
|
private List<string> _allowedScopes;
|
||||||
|
private Response<bool> _result;
|
||||||
|
|
||||||
|
public ScopesAuthoriserTests()
|
||||||
|
{
|
||||||
|
_parser = new Mock<IClaimsParser>();
|
||||||
|
_authoriser = new ScopesAuthoriser(_parser.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_return_ok_if_no_allowed_scopes()
|
||||||
|
{
|
||||||
|
this.Given(_ => GivenTheFollowing(new ClaimsPrincipal()))
|
||||||
|
.And(_ => GivenTheFollowing(new List<string>()))
|
||||||
|
.When(_ => WhenIAuthorise())
|
||||||
|
.Then(_ => ThenTheFollowingIsReturned(new OkResponse<bool>(true)))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_return_ok_if_null_allowed_scopes()
|
||||||
|
{
|
||||||
|
this.Given(_ => GivenTheFollowing(new ClaimsPrincipal()))
|
||||||
|
.And(_ => GivenTheFollowing((List<string>)null))
|
||||||
|
.When(_ => WhenIAuthorise())
|
||||||
|
.Then(_ => ThenTheFollowingIsReturned(new OkResponse<bool>(true)))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_return_error_if_claims_parser_returns_error()
|
||||||
|
{
|
||||||
|
var fakeError = new FakeError();
|
||||||
|
this.Given(_ => GivenTheFollowing(new ClaimsPrincipal()))
|
||||||
|
.And(_ => GivenTheParserReturns(new ErrorResponse<List<string>>(fakeError)))
|
||||||
|
.And(_ => GivenTheFollowing(new List<string>(){"doesntmatter"}))
|
||||||
|
.When(_ => WhenIAuthorise())
|
||||||
|
.Then(_ => ThenTheFollowingIsReturned(new ErrorResponse<bool>(fakeError)))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_match_scopes_and_return_ok_result()
|
||||||
|
{
|
||||||
|
var claimsPrincipal = new ClaimsPrincipal();
|
||||||
|
var allowedScopes = new List<string>(){"someScope"};
|
||||||
|
|
||||||
|
this.Given(_ => GivenTheFollowing(claimsPrincipal))
|
||||||
|
.And(_ => GivenTheParserReturns(new OkResponse<List<string>>(allowedScopes)))
|
||||||
|
.And(_ => GivenTheFollowing(allowedScopes))
|
||||||
|
.When(_ => WhenIAuthorise())
|
||||||
|
.Then(_ => ThenTheFollowingIsReturned(new OkResponse<bool>(true)))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_not_match_scopes_and_return_error_result()
|
||||||
|
{
|
||||||
|
var fakeError = new FakeError();
|
||||||
|
var claimsPrincipal = new ClaimsPrincipal();
|
||||||
|
var allowedScopes = new List<string>(){"someScope"};
|
||||||
|
var userScopes = new List<string>(){"anotherScope"};
|
||||||
|
|
||||||
|
this.Given(_ => GivenTheFollowing(claimsPrincipal))
|
||||||
|
.And(_ => GivenTheParserReturns(new OkResponse<List<string>>(userScopes)))
|
||||||
|
.And(_ => GivenTheFollowing(allowedScopes))
|
||||||
|
.When(_ => WhenIAuthorise())
|
||||||
|
.Then(_ => ThenTheFollowingIsReturned(new ErrorResponse<bool>(fakeError)))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheParserReturns(Response<List<string>> response)
|
||||||
|
{
|
||||||
|
_parser.Setup(x => x.GetValuesByClaimType(It.IsAny<IEnumerable<Claim>>(), It.IsAny<string>())).Returns(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheFollowing(ClaimsPrincipal principal)
|
||||||
|
{
|
||||||
|
_principal = principal;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheFollowing(List<string> allowedScopes)
|
||||||
|
{
|
||||||
|
_allowedScopes = allowedScopes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WhenIAuthorise()
|
||||||
|
{
|
||||||
|
_result = _authoriser.Authorise(_principal, _allowedScopes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheFollowingIsReturned(Response<bool> expected)
|
||||||
|
{
|
||||||
|
_result.Data.ShouldBe(expected.Data);
|
||||||
|
_result.IsError.ShouldBe(expected.IsError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FakeError : Error
|
||||||
|
{
|
||||||
|
public FakeError() : base("fake error", OcelotErrorCode.CannotAddDataError)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
|
||||||
<AssemblyName>Ocelot.UnitTests</AssemblyName>
|
<AssemblyName>Ocelot.UnitTests</AssemblyName>
|
||||||
<PackageId>Ocelot.UnitTests</PackageId>
|
<PackageId>Ocelot.UnitTests</PackageId>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||||
<RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
|
||||||
<RuntimeFrameworkVersion>1.1.1</RuntimeFrameworkVersion>
|
|
||||||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
||||||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
||||||
@ -32,27 +32,22 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-preview-20170106-08" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta2-build1317" />
|
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OAuth" Version="1.1.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20171031-01" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="1.1.1" />
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="1.1.1" />
|
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.1" />
|
<PackageReference Include="Moq" Version="4.7.142" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.1" />
|
<PackageReference Include="Shouldly" Version="3.0.0-beta0003" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.1" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.1" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="1.1.1" />
|
|
||||||
<PackageReference Include="Moq" Version="4.6.38-alpha" />
|
|
||||||
<PackageReference Include="Shouldly" Version="2.8.2" />
|
|
||||||
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
||||||
<PackageReference Include="xunit" Version="2.3.0-beta2-build3683" />
|
<PackageReference Include="xunit" Version="2.3.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Ocelot.Requester.QoS;
|
using Ocelot.Requester.QoS;
|
||||||
|
using Ocelot.Configuration;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
|
||||||
public class HttpRequestBuilderMiddlewareTests : ServerHostedMiddlewareTest
|
public class HttpRequestBuilderMiddlewareTests : ServerHostedMiddlewareTest
|
||||||
@ -50,12 +51,13 @@
|
|||||||
new ReRouteBuilder()
|
new ReRouteBuilder()
|
||||||
.WithRequestIdKey("LSRequestId")
|
.WithRequestIdKey("LSRequestId")
|
||||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||||
|
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true))
|
||||||
.Build());
|
.Build());
|
||||||
|
|
||||||
this.Given(x => x.GivenTheDownStreamUrlIs("any old string"))
|
this.Given(x => x.GivenTheDownStreamUrlIs("any old string"))
|
||||||
.And(x => x.GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(new NoQoSProvider())))
|
.And(x => x.GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(new NoQoSProvider())))
|
||||||
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||||
.And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), true, new NoQoSProvider())))
|
.And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), true, new NoQoSProvider(), false, false)))
|
||||||
.When(x => x.WhenICallTheMiddleware())
|
.When(x => x.WhenICallTheMiddleware())
|
||||||
.Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly())
|
.Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -103,7 +105,11 @@
|
|||||||
_request = new OkResponse<Ocelot.Request.Request>(request);
|
_request = new OkResponse<Ocelot.Request.Request>(request);
|
||||||
|
|
||||||
_requestBuilder
|
_requestBuilder
|
||||||
.Setup(x => x.Build(It.IsAny<HttpRequestMessage>(), It.IsAny<bool>(), It.IsAny<IQoSProvider>()))
|
.Setup(x => x.Build(It.IsAny<HttpRequestMessage>(),
|
||||||
|
It.IsAny<bool>(),
|
||||||
|
It.IsAny<IQoSProvider>(),
|
||||||
|
It.IsAny<bool>(),
|
||||||
|
It.IsAny<bool>()))
|
||||||
.ReturnsAsync(_request);
|
.ReturnsAsync(_request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
private readonly bool _isQos;
|
private readonly bool _isQos;
|
||||||
private readonly IQoSProvider _qoSProvider;
|
private readonly IQoSProvider _qoSProvider;
|
||||||
private readonly HttpRequestMessage _requestMessage;
|
private readonly HttpRequestMessage _requestMessage;
|
||||||
|
private readonly bool _useCookieContainer;
|
||||||
|
private readonly bool _allowAutoRedirect;
|
||||||
|
|
||||||
private Response<Ocelot.Request.Request> _response;
|
private Response<Ocelot.Request.Request> _response;
|
||||||
|
|
||||||
public HttpRequestCreatorTests()
|
public HttpRequestCreatorTests()
|
||||||
@ -22,6 +25,9 @@
|
|||||||
_requestCreator = new HttpRequestCreator();
|
_requestCreator = new HttpRequestCreator();
|
||||||
_isQos = true;
|
_isQos = true;
|
||||||
_qoSProvider = new NoQoSProvider();
|
_qoSProvider = new NoQoSProvider();
|
||||||
|
_useCookieContainer = false;
|
||||||
|
_allowAutoRedirect = false;
|
||||||
|
|
||||||
_requestMessage = new HttpRequestMessage();
|
_requestMessage = new HttpRequestMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,12 +36,19 @@
|
|||||||
{
|
{
|
||||||
this.When(x => x.WhenIBuildARequest())
|
this.When(x => x.WhenIBuildARequest())
|
||||||
.Then(x => x.ThenTheRequestContainsTheRequestMessage())
|
.Then(x => x.ThenTheRequestContainsTheRequestMessage())
|
||||||
|
.Then(x => x.ThenTheRequestContainsTheIsQos())
|
||||||
|
.Then(x => x.ThenTheRequestContainsTheQosProvider())
|
||||||
|
.Then(x => x.ThenTheRequestContainsUseCookieContainer())
|
||||||
|
.Then(x => x.ThenTheRequestContainsAllowAutoRedirect())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WhenIBuildARequest()
|
private void WhenIBuildARequest()
|
||||||
{
|
{
|
||||||
_response = _requestCreator.Build(_requestMessage, _isQos, _qoSProvider).GetAwaiter().GetResult();
|
_response = _requestCreator.Build(_requestMessage,
|
||||||
|
_isQos, _qoSProvider, _useCookieContainer, _allowAutoRedirect)
|
||||||
|
.GetAwaiter()
|
||||||
|
.GetResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenTheRequestContainsTheRequestMessage()
|
private void ThenTheRequestContainsTheRequestMessage()
|
||||||
@ -52,5 +65,15 @@
|
|||||||
{
|
{
|
||||||
_response.Data.QosProvider.ShouldBe(_qoSProvider);
|
_response.Data.QosProvider.ShouldBe(_qoSProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ThenTheRequestContainsUseCookieContainer()
|
||||||
|
{
|
||||||
|
_response.Data.UseCookieContainer.ShouldBe(_useCookieContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheRequestContainsAllowAutoRedirect()
|
||||||
|
{
|
||||||
|
_response.Data.AllowAutoRedirect.ShouldBe(_allowAutoRedirect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_call_scoped_data_repository_correctly()
|
public void should_call_scoped_data_repository_correctly()
|
||||||
{
|
{
|
||||||
this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage(),true, new NoQoSProvider())))
|
this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage(),true, new NoQoSProvider(), false, false)))
|
||||||
.And(x => x.GivenTheRequesterReturns(new HttpResponseMessage()))
|
.And(x => x.GivenTheRequesterReturns(new HttpResponseMessage()))
|
||||||
.And(x => x.GivenTheScopedRepoReturns())
|
.And(x => x.GivenTheScopedRepoReturns())
|
||||||
.When(x => x.WhenICallTheMiddleware())
|
.When(x => x.WhenICallTheMiddleware())
|
||||||
|
@ -42,7 +42,7 @@ namespace Ocelot.UnitTests.Responder
|
|||||||
[InlineData(OcelotErrorCode.RequestTimedOutError)]
|
[InlineData(OcelotErrorCode.RequestTimedOutError)]
|
||||||
public void should_return_service_unavailable(OcelotErrorCode errorCode)
|
public void should_return_service_unavailable(OcelotErrorCode errorCode)
|
||||||
{
|
{
|
||||||
ShouldMapErrorToStatusCode(errorCode, HttpStatusCode.ServiceUnavailable);
|
ShouldMapErrorToStatusCode(OcelotErrorCode.RequestTimedOutError, HttpStatusCode.ServiceUnavailable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ namespace Ocelot.UnitTests.Responder
|
|||||||
// If this test fails then it's because the number of error codes has changed.
|
// If this test fails then it's because the number of error codes has changed.
|
||||||
// You should make the appropriate changes to the test cases here to ensure
|
// You should make the appropriate changes to the test cases here to ensure
|
||||||
// they cover all the error codes, and then modify this assertion.
|
// they cover all the error codes, and then modify this assertion.
|
||||||
Enum.GetNames(typeof(OcelotErrorCode)).Length.ShouldBe(30, "Looks like the number of error codes has changed. Do you need to modify ErrorsToHttpStatusCodeMapper?");
|
Enum.GetNames(typeof(OcelotErrorCode)).Length.ShouldBe(31, "Looks like the number of error codes has changed. Do you need to modify ErrorsToHttpStatusCodeMapper?");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShouldMapErrorToStatusCode(OcelotErrorCode errorCode, HttpStatusCode expectedHttpStatusCode)
|
private void ShouldMapErrorToStatusCode(OcelotErrorCode errorCode, HttpStatusCode expectedHttpStatusCode)
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
namespace Ocelot.UnitTests.TestData
|
namespace Ocelot.UnitTests.TestData
|
||||||
{
|
{
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Ocelot.Configuration.Builder;
|
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
|
|
||||||
public class AuthenticationConfigTestData
|
public class AuthenticationConfigTestData
|
||||||
@ -11,13 +9,6 @@
|
|||||||
{
|
{
|
||||||
yield return new object[]
|
yield return new object[]
|
||||||
{
|
{
|
||||||
"IdentityServer",
|
|
||||||
new IdentityServerConfigBuilder()
|
|
||||||
.WithRequireHttps(true)
|
|
||||||
.WithApiName("test")
|
|
||||||
.WithApiSecret("test")
|
|
||||||
.WithProviderRootUrl("test")
|
|
||||||
.Build(),
|
|
||||||
new FileConfiguration
|
new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -30,15 +21,8 @@
|
|||||||
ReRouteIsCaseSensitive = true,
|
ReRouteIsCaseSensitive = true,
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
|
AuthenticationProviderKey = "Test",
|
||||||
AllowedScopes = new List<string>(),
|
AllowedScopes = new List<string>(),
|
||||||
Provider = "IdentityServer",
|
|
||||||
IdentityServerConfig = new FileIdentityServerConfig
|
|
||||||
{
|
|
||||||
ProviderRootUrl = "http://localhost:51888",
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
AddHeadersToRequest =
|
AddHeadersToRequest =
|
||||||
{
|
{
|
||||||
@ -51,11 +35,6 @@
|
|||||||
|
|
||||||
yield return new object[]
|
yield return new object[]
|
||||||
{
|
{
|
||||||
"Jwt",
|
|
||||||
new JwtConfigBuilder()
|
|
||||||
.WithAudience("a")
|
|
||||||
.WithAuthority("au")
|
|
||||||
.Build(),
|
|
||||||
new FileConfiguration
|
new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -68,13 +47,8 @@
|
|||||||
ReRouteIsCaseSensitive = true,
|
ReRouteIsCaseSensitive = true,
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
|
AuthenticationProviderKey = "Test",
|
||||||
AllowedScopes = new List<string>(),
|
AllowedScopes = new List<string>(),
|
||||||
Provider = "IdentityServer",
|
|
||||||
JwtConfig = new FileJwtConfig
|
|
||||||
{
|
|
||||||
Audience = "a",
|
|
||||||
Authority = "au"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
AddHeadersToRequest =
|
AddHeadersToRequest =
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Cake" version="0.17.0" />
|
<package id="Cake" version="0.23.0" />
|
||||||
</packages>
|
</packages>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user