Skip to content

Commit

Permalink
Merge pull request #17 from Project-MONAI/nds_addbasiceauth
Browse files Browse the repository at this point in the history
fix for basic auth
  • Loading branch information
neildsouth authored Dec 14, 2022
2 parents 0f62381 + d13f616 commit 7a391f5
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/Authentication/Middleware/BasicAuthorizationMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Monai.Deploy.Security.Authentication.Configurations;
using Monai.Deploy.Security.Authentication.Extensions;

namespace Monai.Deploy.Security.Authentication.Middleware
{
Expand All @@ -49,7 +48,8 @@ public BasicAuthorizationMiddleware(
public async Task InvokeAsync(HttpContext httpContext)
{

if (_options.Value.BasicAuthEnabled(_logger) is false)
if ((_options.Value.BypassAuthentication.HasValue && _options.Value.BypassAuthentication.Value is true)
|| _options.Value.BasicAuthEnabled(_logger) is false)
{
await _next(httpContext).ConfigureAwait(false);
return;
Expand All @@ -70,6 +70,7 @@ public async Task InvokeAsync(HttpContext httpContext)
var identity = new ClaimsIdentity(claims, "Basic");
var claimsPrincipal = new ClaimsPrincipal(identity);
httpContext.User = claimsPrincipal;
await _next(httpContext).ConfigureAwait(false);
return;
}
}
Expand Down
138 changes: 138 additions & 0 deletions src/Authentication/Tests/BasicAuthorizationMiddlewareTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
* Copyright 2022 MONAI Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

using System.Net;
using System.Text;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.TestHost;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Monai.Deploy.Security.Authentication.Configurations;
using Monai.Deploy.Security.Authentication.Extensions;

namespace Monai.Deploy.Security.Authentication.Tests
{
public partial class BasicAuthorizationMiddlewareTest
{


[Fact]
public async Task GivenConfigurationFileToBypassAuthentication_ExpectToBypassAuthentication()
{
using var host = await new HostBuilder().ConfigureWebHost(SetupWebServer("test.basicbypass.json")).StartAsync().ConfigureAwait(false);

var server = host.GetTestServer();
server.BaseAddress = new Uri("https://example.com/");

var client = server.CreateClient();
var responseMessage = await client.GetAsync("api/Test").ConfigureAwait(false);

Assert.True(responseMessage.IsSuccessStatusCode);
}



[Fact]
public async Task GivenConfigurationFileWithBasicConfigured_WhenUserIsNotAuthenticated_ExpectToDenyRequest()
{
using var host = await new HostBuilder().ConfigureWebHost(SetupWebServer("test.basic.json")).StartAsync().ConfigureAwait(false);

var server = host.GetTestServer();
server.BaseAddress = new Uri("https://example.com/");

var client = server.CreateClient();
var responseMessage = await client.GetAsync("api/Test").ConfigureAwait(false);

Assert.Equal(HttpStatusCode.Unauthorized, responseMessage.StatusCode);
}

[Fact]
public async Task GivenConfigurationFileWithBasicConfigured_WhenUserIsAuthenticated_ExpectToAllowRequest()
{
using var host = await new HostBuilder().ConfigureWebHost(SetupWebServer("test.basic.json")).StartAsync().ConfigureAwait(false);

var server = host.GetTestServer();
server.BaseAddress = new Uri("https://example.com/");

var client = server.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", $"Basic {Convert.ToBase64String(Encoding.UTF8.GetBytes("user:pass"))}");
var responseMessage = await client.GetAsync("api/Test").ConfigureAwait(false);

Assert.Equal(HttpStatusCode.OK, responseMessage.StatusCode);
}

[Fact]
public async Task GivenConfigurationFileWithBasicConfigured_WhenHeaderIsInvalid_ExpectToDenyRequest()
{
using var host = await new HostBuilder().ConfigureWebHost(SetupWebServer("test.basic.json")).StartAsync().ConfigureAwait(false);

var server = host.GetTestServer();
server.BaseAddress = new Uri("https://example.com/");

var client = server.CreateClient();
client.DefaultRequestHeaders.Add("Authorization", $"BasicBad {Convert.ToBase64String(Encoding.UTF8.GetBytes("user:pass"))}");
var responseMessage = await client.GetAsync("api/Test").ConfigureAwait(false);

Assert.Equal(HttpStatusCode.Unauthorized, responseMessage.StatusCode);
}

private static Action<IWebHostBuilder> SetupWebServer(string configFile) => webBuilder =>
{
webBuilder
.ConfigureAppConfiguration((builderContext, config) =>
{
config.Sources.Clear();
config.AddJsonFile(configFile, optional: false);
_ = config.Build();
})
.ConfigureLogging((hostContext, logging) =>
{
logging.AddDebug();
logging.AddConsole();
})
.ConfigureServices((hostContext, services) =>
{
services.AddOptions<AuthenticationOptions>().Bind(hostContext.Configuration.GetSection("MonaiDeployAuthentication"));

services.AddControllers();
services.AddMonaiAuthentication();

services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, op =>
{
var config = new OpenIdConnectConfiguration()
{
Issuer = Guid.NewGuid().ToString(),
};

config.SigningKeys.Add(EndpointAuthorizationMiddlewareTest.MockJwtTokenHandler.SecurityKey);
op.Configuration = config;
});
})
.Configure(app =>
{
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpointAuthorizationMiddleware();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
})
.UseTestServer();
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ public async Task GivenConfigurationFileWithBasicConfigured_WhenUserIsAuthentica

Assert.Equal(HttpStatusCode.OK, responseMessage.StatusCode);
}

[Fact]
public async Task GivenConfigurationFileWithBasicConfigured_WhenHeaderIsInvalid_ExpectToDenyRequest()
{
Expand Down
Empty file modified src/Authentication/Tests/MockJwtTokenHandler.cs
100644 → 100755
Empty file.
2 changes: 2 additions & 0 deletions src/Authentication/Tests/Monai.Deploy.Security.Authentication.Tests.csproj
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,6 @@
</None>
</ItemGroup>

<ProjectExtensions><VisualStudio><UserProperties test_1basic_1json__JsonSchema="BasicAuthorizationMiddlewareTestBasicAuthorizationMiddlewareTestBasicAuthorizationMiddlewareTest" /></VisualStudio></ProjectExtensions>

</Project>
9 changes: 9 additions & 0 deletions src/Authentication/Tests/test.basicbypass.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"MonaiDeployAuthentication": {
"BypassAuthentication": true,
"basicAuth": {
"userName": "user",
"password": "pass"
}
}
}

0 comments on commit 7a391f5

Please sign in to comment.