Add support for AzureAD authentication for REST admin interface (#637)

This commit is contained in:
Stef Heyenrath
2021-10-20 16:39:51 +02:00
committed by GitHub
parent 48b3e7a305
commit affe388e30
16 changed files with 230 additions and 45 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<VersionPrefix>1.4.23</VersionPrefix> <VersionPrefix>1.4.24</VersionPrefix>
<PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes> <PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes>
<PackageIcon>WireMock.Net-Logo.png</PackageIcon> <PackageIcon>WireMock.Net-Logo.png</PackageIcon>
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl> <PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
@@ -77,9 +77,17 @@ namespace WireMock.Net.ConsoleApplication
System.Console.WriteLine("WireMockServer listening at {0}", string.Join(",", server.Urls)); System.Console.WriteLine("WireMockServer listening at {0}", string.Join(",", server.Urls));
server.SetBasicAuthentication("a", "b"); server.SetBasicAuthentication("a", "b");
//server.SetAzureADAuthentication("6c2a4722-f3b9-4970-b8fc-fac41e29stef", "8587fde1-7824-42c7-8592-faf92b04stef");
// server.AllowPartialMapping(); // server.AllowPartialMapping();
server.Given(Request.Create().WithPath("/mypath").UsingPost())
.RespondWith(Response.Create()
.WithHeader("Content-Type", "application/json")
.WithBodyAsJson("{{JsonPath.SelectToken request.body \"..name\"}}")
.WithTransformer()
);
server server
.Given(Request.Create().WithPath(p => p.Contains("x")).UsingGet()) .Given(Request.Create().WithPath(p => p.Contains("x")).UsingGet())
.AtPriority(4) .AtPriority(4)
@@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using JetBrains.Annotations; using JetBrains.Annotations;
@@ -104,9 +104,9 @@ namespace WireMock.Server
void ReadStaticMappings([CanBeNull] string folder = null); void ReadStaticMappings([CanBeNull] string folder = null);
/// <summary> /// <summary>
/// Removes the basic authentication. /// Removes the authentication.
/// </summary> /// </summary>
void RemoveBasicAuthentication(); void RemoveAuthentication();
/// <summary> /// <summary>
/// Resets LogEntries and Mappings. /// Resets LogEntries and Mappings.
@@ -134,6 +134,13 @@ namespace WireMock.Server
/// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param> /// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param>
void SaveStaticMappings([CanBeNull] string folder = null); void SaveStaticMappings([CanBeNull] string folder = null);
/// <summary>
/// Sets the basic authentication.
/// </summary>
/// <param name="tenant">The Tenant.</param>
/// <param name="audience">The Audience or Resource.</param>
void SetAzureADAuthentication([NotNull] string tenant, [NotNull] string audience);
/// <summary> /// <summary>
/// Sets the basic authentication. /// Sets the basic authentication.
/// </summary> /// </summary>
@@ -0,0 +1,71 @@
#if !NETSTANDARD1_3
using System.Globalization;
using System.IdentityModel.Tokens.Jwt;
using System.Text.RegularExpressions;
using AnyOfTypes;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using WireMock.Matchers;
using WireMock.Models;
namespace WireMock.Authentication
{
/// <summary>
/// https://www.c-sharpcorner.com/article/how-to-validate-azure-ad-token-using-console-application/
/// https://stackoverflow.com/questions/38684865/validation-of-an-azure-ad-bearer-token-in-a-console-application
/// </summary>
internal class AzureADAuthenticationMatcher : IStringMatcher
{
private const string BearerPrefix = "Bearer ";
private readonly string _audience;
private readonly string _stsDiscoveryEndpoint;
public AzureADAuthenticationMatcher(string tenant, string audience)
{
_audience = audience;
_stsDiscoveryEndpoint = string.Format(CultureInfo.InvariantCulture, "https://login.microsoftonline.com/{0}/.well-known/openid-configuration", tenant);
}
public string Name => nameof(AzureADAuthenticationMatcher);
public MatchBehaviour MatchBehaviour => MatchBehaviour.AcceptOnMatch;
public bool ThrowException => false;
public AnyOf<string, StringPattern>[] GetPatterns()
{
return new AnyOf<string, StringPattern>[0];
}
public double IsMatch(string input)
{
var token = Regex.Replace(input, BearerPrefix, string.Empty, RegexOptions.IgnoreCase);
try
{
var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(_stsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever());
var config = configManager.GetConfigurationAsync().GetAwaiter().GetResult();
var validationParameters = new TokenValidationParameters
{
ValidAudience = _audience,
ValidIssuer = config.Issuer,
IssuerSigningKeys = config.SigningKeys,
ValidateLifetime = true
};
// Throws an Exception as the token is invalid (expired, invalid-formatted, etc.)
new JwtSecurityTokenHandler().ValidateToken(token, validationParameters, out var _);
return MatchScores.Perfect;
}
catch
{
return MatchScores.Mismatch;
}
}
}
}
#endif
@@ -0,0 +1,20 @@
using System;
using System.Text;
using WireMock.Matchers;
namespace WireMock.Authentication
{
internal class BasicAuthenticationMatcher : RegexMatcher
{
public BasicAuthenticationMatcher(string username, string password) : base(BuildPattern(username, password))
{
}
public override string Name => nameof(BasicAuthenticationMatcher);
private static string BuildPattern(string username, string password)
{
return "^(?i)BASIC " + Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password)) + "$";
}
}
}
@@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using WireMock.Handlers; using WireMock.Handlers;
using WireMock.Logging; using WireMock.Logging;
@@ -19,7 +19,7 @@ namespace WireMock.Owin
TimeSpan? RequestProcessingDelay { get; set; } TimeSpan? RequestProcessingDelay { get; set; }
IStringMatcher AuthorizationMatcher { get; set; } IStringMatcher AuthenticationMatcher { get; set; }
bool? AllowPartialMapping { get; set; } bool? AllowPartialMapping { get; set; }
+2 -2
View File
@@ -113,10 +113,10 @@ namespace WireMock.Owin
logRequest = targetMapping.LogMapping; logRequest = targetMapping.LogMapping;
if (targetMapping.IsAdminInterface && _options.AuthorizationMatcher != null) if (targetMapping.IsAdminInterface && _options.AuthenticationMatcher != null)
{ {
bool present = request.Headers.TryGetValue(HttpKnownHeaderNames.Authorization, out WireMockList<string> authorization); bool present = request.Headers.TryGetValue(HttpKnownHeaderNames.Authorization, out WireMockList<string> authorization);
if (!present || _options.AuthorizationMatcher.IsMatch(authorization.ToString()) < MatchScores.Perfect) if (!present || _options.AuthenticationMatcher.IsMatch(authorization.ToString()) < MatchScores.Perfect)
{ {
_options.Logger.Error("HttpStatusCode set to 401"); _options.Logger.Error("HttpStatusCode set to 401");
response = ResponseMessageBuilder.Create(null, 401); response = ResponseMessageBuilder.Create(null, 401);
@@ -19,7 +19,7 @@ namespace WireMock.Owin
public TimeSpan? RequestProcessingDelay { get; set; } public TimeSpan? RequestProcessingDelay { get; set; }
public IStringMatcher AuthorizationMatcher { get; set; } public IStringMatcher AuthenticationMatcher { get; set; }
public bool? AllowPartialMapping { get; set; } public bool? AllowPartialMapping { get; set; }
+25 -6
View File
@@ -9,6 +9,7 @@ using System.Threading;
using JetBrains.Annotations; using JetBrains.Annotations;
using Newtonsoft.Json; using Newtonsoft.Json;
using WireMock.Admin.Mappings; using WireMock.Admin.Mappings;
using WireMock.Authentication;
using WireMock.Exceptions; using WireMock.Exceptions;
using WireMock.Handlers; using WireMock.Handlers;
using WireMock.Logging; using WireMock.Logging;
@@ -302,6 +303,11 @@ namespace WireMock.Server
SetBasicAuthentication(settings.AdminUsername, settings.AdminPassword); SetBasicAuthentication(settings.AdminUsername, settings.AdminPassword);
} }
if (!string.IsNullOrEmpty(settings.AdminAzureADTenant) && !string.IsNullOrEmpty(settings.AdminAzureADAudience))
{
SetAzureADAuthentication(settings.AdminAzureADTenant, settings.AdminAzureADAudience);
}
InitAdmin(); InitAdmin();
} }
@@ -404,22 +410,35 @@ namespace WireMock.Server
_options.AllowPartialMapping = allow; _options.AllowPartialMapping = allow;
} }
/// <inheritdoc cref="IWireMockServer.SetBasicAuthentication" /> /// <inheritdoc cref="IWireMockServer.SetAzureADAuthentication(string, string)" />
[PublicAPI]
public void SetAzureADAuthentication([NotNull] string tenant, [NotNull] string audience)
{
Check.NotNull(tenant, nameof(tenant));
Check.NotNull(audience, nameof(audience));
#if NETSTANDARD1_3
throw new NotSupportedException("AzureADAuthentication is not supported for NETStandard 1.3");
#else
_options.AuthenticationMatcher = new AzureADAuthenticationMatcher(tenant, audience);
#endif
}
/// <inheritdoc cref="IWireMockServer.SetBasicAuthentication(string, string)" />
[PublicAPI] [PublicAPI]
public void SetBasicAuthentication([NotNull] string username, [NotNull] string password) public void SetBasicAuthentication([NotNull] string username, [NotNull] string password)
{ {
Check.NotNull(username, nameof(username)); Check.NotNull(username, nameof(username));
Check.NotNull(password, nameof(password)); Check.NotNull(password, nameof(password));
string authorization = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password)); _options.AuthenticationMatcher = new BasicAuthenticationMatcher(username, password);
_options.AuthorizationMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, "^(?i)BASIC " + authorization + "$");
} }
/// <inheritdoc cref="IWireMockServer.RemoveBasicAuthentication" /> /// <inheritdoc cref="IWireMockServer.RemoveAuthentication" />
[PublicAPI] [PublicAPI]
public void RemoveBasicAuthentication() public void RemoveAuthentication()
{ {
_options.AuthorizationMatcher = null; _options.AuthenticationMatcher = null;
} }
/// <inheritdoc cref="IWireMockServer.SetMaxRequestLogCount" /> /// <inheritdoc cref="IWireMockServer.SetMaxRequestLogCount" />
@@ -1,4 +1,4 @@
using System; using System;
using HandlebarsDotNet; using HandlebarsDotNet;
using JetBrains.Annotations; using JetBrains.Annotations;
using WireMock.Handlers; using WireMock.Handlers;
@@ -88,6 +88,18 @@ namespace WireMock.Settings
[PublicAPI] [PublicAPI]
string AdminPassword { get; set; } string AdminPassword { get; set; }
/// <summary>
/// The AzureAD Tenant needed for __admin access.
/// </summary>
[PublicAPI]
string AdminAzureADTenant { get; set; }
/// <summary>
/// The AzureAD Audience / Resource for __admin access.
/// </summary>
[PublicAPI]
string AdminAzureADAudience { get; set; }
/// <summary> /// <summary>
/// The RequestLog expiration in hours (optional). /// The RequestLog expiration in hours (optional).
/// </summary> /// </summary>
@@ -1,4 +1,4 @@
using System; using System;
using HandlebarsDotNet; using HandlebarsDotNet;
using JetBrains.Annotations; using JetBrains.Annotations;
using Newtonsoft.Json; using Newtonsoft.Json;
@@ -64,6 +64,14 @@ namespace WireMock.Settings
[PublicAPI] [PublicAPI]
public string AdminPassword { get; set; } public string AdminPassword { get; set; }
/// <inheritdoc cref="IWireMockServerSettings.AdminAzureADTenant"/>
[PublicAPI]
public string AdminAzureADTenant { get; set; }
/// <inheritdoc cref="IWireMockServerSettings.AdminAzureADAudience"/>
[PublicAPI]
public string AdminAzureADAudience { get; set; }
/// <inheritdoc cref="IWireMockServerSettings.RequestLogExpirationDuration"/> /// <inheritdoc cref="IWireMockServerSettings.RequestLogExpirationDuration"/>
[PublicAPI] [PublicAPI]
public int? RequestLogExpirationDuration { get; set; } public int? RequestLogExpirationDuration { get; set; }
@@ -1,4 +1,4 @@
using JetBrains.Annotations; using JetBrains.Annotations;
using WireMock.Logging; using WireMock.Logging;
using WireMock.Validation; using WireMock.Validation;
@@ -39,6 +39,8 @@ namespace WireMock.Settings
WatchStaticMappingsInSubdirectories = parser.GetBoolValue("WatchStaticMappingsInSubdirectories"), WatchStaticMappingsInSubdirectories = parser.GetBoolValue("WatchStaticMappingsInSubdirectories"),
AdminUsername = parser.GetStringValue("AdminUsername"), AdminUsername = parser.GetStringValue("AdminUsername"),
AdminPassword = parser.GetStringValue("AdminPassword"), AdminPassword = parser.GetStringValue("AdminPassword"),
AdminAzureADTenant = parser.GetStringValue(nameof(IWireMockServerSettings.AdminAzureADTenant)),
AdminAzureADAudience = parser.GetStringValue(nameof(IWireMockServerSettings.AdminAzureADAudience)),
MaxRequestLogCount = parser.GetIntValue("MaxRequestLogCount"), MaxRequestLogCount = parser.GetIntValue("MaxRequestLogCount"),
RequestLogExpirationDuration = parser.GetIntValue("RequestLogExpirationDuration"), RequestLogExpirationDuration = parser.GetIntValue("RequestLogExpirationDuration"),
AllowCSharpCodeMatcher = parser.GetBoolValue("AllowCSharpCodeMatcher"), AllowCSharpCodeMatcher = parser.GetBoolValue("AllowCSharpCodeMatcher"),
+16 -14
View File
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Description>Lightweight Http Mocking Server for .Net, inspired by WireMock from the Java landscape.</Description> <Description>Lightweight Http Mocking Server for .Net, inspired by WireMock from the Java landscape.</Description>
<AssemblyTitle>WireMock.Net</AssemblyTitle> <AssemblyTitle>WireMock.Net</AssemblyTitle>
@@ -50,16 +50,17 @@
<DefineConstants>USE_ASPNETCORE;NET46</DefineConstants> <DefineConstants>USE_ASPNETCORE;NET46</DefineConstants>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" PrivateAssets="All" /> <PackageReference Include="JetBrains.Annotations" Version="2020.1.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" /> <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="SimMetrics.Net" Version="1.0.5" /> <PackageReference Include="SimMetrics.Net" Version="1.0.5" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.12" /> <!--<PackageReference Include="Stef.Validation" Version="0.0.3" />-->
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.12" /> <PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.12" />
<PackageReference Include="JmesPath.Net" Version="1.0.125" /> <PackageReference Include="RandomDataGenerator.Net" Version="1.0.12" />
<PackageReference Include="AnyOf" Version="0.2.0" /> <PackageReference Include="JmesPath.Net" Version="1.0.125" />
</ItemGroup> <PackageReference Include="AnyOf" Version="0.2.0" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Debug - Sonar'"> <ItemGroup Condition="'$(Configuration)' == 'Debug - Sonar'">
<PackageReference Include="SonarAnalyzer.CSharp" Version="7.8.0.7320"> <PackageReference Include="SonarAnalyzer.CSharp" Version="7.8.0.7320">
@@ -68,9 +69,10 @@
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' != 'netstandard1.3' "> <ItemGroup Condition=" '$(TargetFramework)' != 'netstandard1.3' ">
<PackageReference Include="XPath2.Extensions" Version="1.1.0" /> <PackageReference Include="XPath2.Extensions" Version="1.1.0" />
</ItemGroup> <PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="6.12.2" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net451' or '$(TargetFramework)' == 'net452' "> <ItemGroup Condition=" '$(TargetFramework)' == 'net451' or '$(TargetFramework)' == 'net452' ">
<!-- Required for WebRequestHandler --> <!-- Required for WebRequestHandler -->
@@ -96,7 +96,7 @@ namespace WireMock.Net.Tests.Owin
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1", null, new Dictionary<string, string[]>()); var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1", null, new Dictionary<string, string[]>());
_requestMapperMock.Setup(m => m.MapAsync(It.IsAny<IRequest>(), It.IsAny<IWireMockMiddlewareOptions>())).ReturnsAsync(request); _requestMapperMock.Setup(m => m.MapAsync(It.IsAny<IRequest>(), It.IsAny<IWireMockMiddlewareOptions>())).ReturnsAsync(request);
_optionsMock.SetupGet(o => o.AuthorizationMatcher).Returns(new ExactMatcher()); _optionsMock.SetupGet(o => o.AuthenticationMatcher).Returns(new ExactMatcher());
_mappingMock.SetupGet(m => m.IsAdminInterface).Returns(true); _mappingMock.SetupGet(m => m.IsAdminInterface).Returns(true);
var result = new MappingMatcherResult { Mapping = _mappingMock.Object }; var result = new MappingMatcherResult { Mapping = _mappingMock.Object };
@@ -119,7 +119,7 @@ namespace WireMock.Net.Tests.Owin
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1", null, new Dictionary<string, string[]> { { "h", new[] { "x" } } }); var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1", null, new Dictionary<string, string[]> { { "h", new[] { "x" } } });
_requestMapperMock.Setup(m => m.MapAsync(It.IsAny<IRequest>(), It.IsAny<IWireMockMiddlewareOptions>())).ReturnsAsync(request); _requestMapperMock.Setup(m => m.MapAsync(It.IsAny<IRequest>(), It.IsAny<IWireMockMiddlewareOptions>())).ReturnsAsync(request);
_optionsMock.SetupGet(o => o.AuthorizationMatcher).Returns(new ExactMatcher()); _optionsMock.SetupGet(o => o.AuthenticationMatcher).Returns(new ExactMatcher());
_mappingMock.SetupGet(m => m.IsAdminInterface).Returns(true); _mappingMock.SetupGet(m => m.IsAdminInterface).Returns(true);
var result = new MappingMatcherResult { Mapping = _mappingMock.Object }; var result = new MappingMatcherResult { Mapping = _mappingMock.Object };
@@ -152,7 +152,7 @@ namespace WireMock.Net.Tests.Owin
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1", null, new Dictionary<string, string[]>()); var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1", null, new Dictionary<string, string[]>());
_requestMapperMock.Setup(m => m.MapAsync(It.IsAny<IRequest>(), It.IsAny<IWireMockMiddlewareOptions>())).ReturnsAsync(request); _requestMapperMock.Setup(m => m.MapAsync(It.IsAny<IRequest>(), It.IsAny<IWireMockMiddlewareOptions>())).ReturnsAsync(request);
_optionsMock.SetupGet(o => o.AuthorizationMatcher).Returns(new ExactMatcher()); _optionsMock.SetupGet(o => o.AuthenticationMatcher).Returns(new ExactMatcher());
var fileSystemHandlerMock = new Mock<IFileSystemHandler>(); var fileSystemHandlerMock = new Mock<IFileSystemHandler>();
fileSystemHandlerMock.Setup(f => f.GetMappingFolder()).Returns("m"); fileSystemHandlerMock.Setup(f => f.GetMappingFolder()).Returns("m");
@@ -201,7 +201,7 @@ namespace WireMock.Net.Tests.Owin
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1", null, new Dictionary<string, string[]>()); var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1", null, new Dictionary<string, string[]>());
_requestMapperMock.Setup(m => m.MapAsync(It.IsAny<IRequest>(), It.IsAny<IWireMockMiddlewareOptions>())).ReturnsAsync(request); _requestMapperMock.Setup(m => m.MapAsync(It.IsAny<IRequest>(), It.IsAny<IWireMockMiddlewareOptions>())).ReturnsAsync(request);
_optionsMock.SetupGet(o => o.AuthorizationMatcher).Returns(new ExactMatcher()); _optionsMock.SetupGet(o => o.AuthenticationMatcher).Returns(new ExactMatcher());
var fileSystemHandlerMock = new Mock<IFileSystemHandler>(); var fileSystemHandlerMock = new Mock<IFileSystemHandler>();
fileSystemHandlerMock.Setup(f => f.GetMappingFolder()).Returns("m"); fileSystemHandlerMock.Setup(f => f.GetMappingFolder()).Returns("m");
@@ -1,3 +1,4 @@
using FluentAssertions;
using NFluent; using NFluent;
using WireMock.Matchers; using WireMock.Matchers;
using WireMock.Owin; using WireMock.Owin;
@@ -19,26 +20,43 @@ namespace WireMock.Net.Tests
// Assert // Assert
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options"); var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
Check.That(options.AuthorizationMatcher.Name).IsEqualTo("RegexMatcher"); Check.That(options.AuthenticationMatcher.Name).IsEqualTo("BasicAuthenticationMatcher");
Check.That(options.AuthorizationMatcher.MatchBehaviour).IsEqualTo(MatchBehaviour.AcceptOnMatch); Check.That(options.AuthenticationMatcher.MatchBehaviour).IsEqualTo(MatchBehaviour.AcceptOnMatch);
Check.That(options.AuthorizationMatcher.GetPatterns()).ContainsExactly("^(?i)BASIC eDp5$"); Check.That(options.AuthenticationMatcher.GetPatterns()).ContainsExactly("^(?i)BASIC eDp5$");
server.Stop(); server.Stop();
} }
[Fact] [Fact]
public void WireMockServer_Authentication_RemoveBasicAuthentication() public void WireMockServer_Authentication_SetSetAzureADAuthentication()
{
// Assign
var server = WireMockServer.Start();
// Act
server.SetAzureADAuthentication("x", "y");
// Assert
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
options.AuthenticationMatcher.Name.Should().Be("AzureADAuthenticationMatcher");
options.AuthenticationMatcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch);
server.Stop();
}
[Fact]
public void WireMockServer_Authentication_RemoveAuthentication()
{ {
// Assign // Assign
var server = WireMockServer.Start(); var server = WireMockServer.Start();
server.SetBasicAuthentication("x", "y"); server.SetBasicAuthentication("x", "y");
// Act // Act
server.RemoveBasicAuthentication(); server.RemoveAuthentication();
// Assert // Assert
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options"); var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
Check.That(options.AuthorizationMatcher).IsNull(); Check.That(options.AuthenticationMatcher).IsNull();
server.Stop(); server.Stop();
} }
@@ -1,6 +1,8 @@
using System.Linq;
using FluentAssertions;
using Moq; using Moq;
using NFluent; using NFluent;
using System.Linq; using WireMock.Authentication;
using WireMock.Logging; using WireMock.Logging;
using WireMock.Owin; using WireMock.Owin;
using WireMock.Server; using WireMock.Server;
@@ -32,7 +34,23 @@ namespace WireMock.Net.Tests
// Assert // Assert
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options"); var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
Check.That(options.AuthorizationMatcher).IsNotNull(); options.AuthenticationMatcher.Should().NotBeNull().And.BeOfType<BasicAuthenticationMatcher>();
}
[Fact]
public void WireMockServer_WireMockServerSettings_StartAdminInterfaceTrue_AzureADAuthenticationIsSet()
{
// Assign and Act
var server = WireMockServer.Start(new WireMockServerSettings
{
StartAdminInterface = true,
AdminAzureADTenant = "t",
AdminAzureADAudience = "a"
});
// Assert
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
options.AuthenticationMatcher.Should().NotBeNull().And.BeOfType<AzureADAuthenticationMatcher>();
} }
[Fact] [Fact]
@@ -48,7 +66,7 @@ namespace WireMock.Net.Tests
// Assert // Assert
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options"); var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
Check.That(options.AuthorizationMatcher).IsNull(); Check.That(options.AuthenticationMatcher).IsNull();
} }
[Fact] [Fact]