Skip to content

Commit

Permalink
Internal and External auth cannot be enabled at the same time, redirect
Browse files Browse the repository at this point in the history
  • Loading branch information
antoineatstariongroup committed Jan 22, 2025
1 parent d539378 commit fe2d7f8
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 37 deletions.
12 changes: 2 additions & 10 deletions CometServer.Tests/Configuration/AppConfigServiceTestFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,12 @@ namespace CometServer.Tests.Configuration
{
using System.IO;

using CDP4Authentication;

using CometServer.Authentication.Basic;
using CometServer.Authentication.Bearer;
using CometServer.Configuration;

using Microsoft.Extensions.Configuration;

using Moq;

using NUnit.Framework;

/// <summary>
Expand All @@ -45,7 +41,6 @@ namespace CometServer.Tests.Configuration
public class AppConfigServiceTestFixture
{
private IConfiguration configuration;
private Mock<IAuthenticationPluginInjector> pluginInjector;

[SetUp]
public void SetUp()
Expand All @@ -59,15 +54,12 @@ public void SetUp()

// Build the IConfiguration instance
this.configuration = configurationBuilder.Build();

this.pluginInjector = new Mock<IAuthenticationPluginInjector>();
this.pluginInjector.Setup(x => x.Connectors).Returns([]);
}

[Test]
public void Verify_that_configuration_is_loaded_from_appsettings()
{
var appConfigService = new AppConfigService(this.configuration, this.pluginInjector.Object);
var appConfigService = new AppConfigService(this.configuration);

Assert.Multiple(() =>
{
Expand All @@ -91,7 +83,7 @@ public void Verify_that_configuration_is_loaded_from_appsettings()
Assert.That(appConfigService.AppConfig.AuthenticationConfig.ExternalJwtAuthenticationConfig.IsEnabled, Is.True);
Assert.That(appConfigService.IsAuthenticationSchemeEnabled(BasicAuthenticationDefaults.AuthenticationScheme), Is.True);
Assert.That(appConfigService.IsAuthenticationSchemeEnabled(JwtBearerDefaults.LocalAuthenticationScheme), Is.True);
Assert.That(appConfigService.IsAuthenticationSchemeEnabled(JwtBearerDefaults.ExternalAuthenticationScheme), Is.False);
Assert.That(appConfigService.IsAuthenticationSchemeEnabled(JwtBearerDefaults.ExternalAuthenticationScheme), Is.True);
});
}
}
Expand Down
16 changes: 2 additions & 14 deletions CometServer/Configuration/AppConfigService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@

namespace CometServer.Configuration
{
using System.Linq;

using CDP4Authentication;

using CometServer.Authentication.Basic;
using CometServer.Authentication.Bearer;

Expand All @@ -38,22 +34,15 @@ namespace CometServer.Configuration
/// </summary>
public class AppConfigService : IAppConfigService
{
/// <summary>
/// Gets the injected <see cref="IAuthenticationPluginInjector"/>, uses to check wheter that external JWT authentication is enabled or not
/// </summary>
private readonly IAuthenticationPluginInjector authenticationPluginInjector;

/// <summary>
/// Initializes a new instance of the <see cref="AppConfigService"/>
/// </summary>
/// <param name="configuration">
/// The <see cref="IConfiguration"/> used to set the properties
/// </param>
/// <param name="authenticationPluginInjector">The injected <see cref="IAuthenticationPluginInjector"/>, uses to check wheter that external JWT authentication is enabled or not</param>
public AppConfigService(IConfiguration configuration, IAuthenticationPluginInjector authenticationPluginInjector)
public AppConfigService(IConfiguration configuration)
{
this.AppConfig = new AppConfig(configuration);
this.authenticationPluginInjector = authenticationPluginInjector;
}

/// <summary>
Expand All @@ -72,8 +61,7 @@ public bool IsAuthenticationSchemeEnabled(string schemeName)
{
BasicAuthenticationDefaults.AuthenticationScheme => this.AppConfig.AuthenticationConfig.BasicAuthenticationConfig.IsEnabled,
JwtBearerDefaults.LocalAuthenticationScheme => this.AppConfig.AuthenticationConfig.LocalJwtAuthenticationConfig.IsEnabled,
JwtBearerDefaults.ExternalAuthenticationScheme => this.AppConfig.AuthenticationConfig.ExternalJwtAuthenticationConfig.IsEnabled
&& this.authenticationPluginInjector.Connectors.Any(x => x.Name == "CDP4ExternalJwtAuthentication" && x.Properties.IsEnabled),
JwtBearerDefaults.ExternalAuthenticationScheme => this.AppConfig.AuthenticationConfig.ExternalJwtAuthenticationConfig.IsEnabled,
_ => false
};
}
Expand Down
6 changes: 6 additions & 0 deletions CometServer/Configuration/ExternalJwtAuthenticationConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public ExternalJwtAuthenticationConfig(IConfiguration configuration)
this.Authority = configuration["Authentication:ExternalJwtBearer:Authority"];
this.ValidIssuer = configuration["Authentication:ExternalJwtBearer:ValidIssuer"];
this.IdentifierClaimName = configuration["Authentication:ExternalJwtBearer:IdentifierClaimName"];
this.RedirectUrl = configuration["Authentication:ExternalJwtBearer:RedirectUrl"];
this.PersonIdentifierPropertyKind = Enum.Parse<PersonIdentifierPropertyKind>(configuration["Authentication:ExternalJwtBearer:PersonIdentifierPropertyKind"]!);
}

Expand Down Expand Up @@ -90,5 +91,10 @@ public ExternalJwtAuthenticationConfig(IConfiguration configuration)
/// Gets or sets the <see cref="PersonIdentifierPropertyKind"/> to use for the authorization part
/// </summary>
public PersonIdentifierPropertyKind PersonIdentifierPropertyKind { get; set; }

/// <summary>
/// Gets or sets the Url that should be sent back to unauthenticated client
/// </summary>
public string RedirectUrl { get; set; }
}
}
10 changes: 7 additions & 3 deletions CometServer/Modules/Authentication/AuthenticationModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,16 @@
namespace CometServer.Modules
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using Carter;
using Carter.Response;

using CometServer.Authentication;
using CometServer.Authentication.Bearer;
using CometServer.Configuration;

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
Expand Down Expand Up @@ -86,7 +85,12 @@ public override void AddRoutes(IEndpointRouteBuilder app)
private static Task ProvideEnabledAuthenticationScheme(HttpResponse res, IAppConfigService appConfigService)
{
var enabledSchemes = ApiBase.AuthenticationSchemes.Where(appConfigService.IsAuthenticationSchemeEnabled).ToList();
return res.AsJson(enabledSchemes);

var redirectUrl = appConfigService.IsAuthenticationSchemeEnabled(JwtBearerDefaults.ExternalAuthenticationScheme)
? appConfigService.AppConfig.AuthenticationConfig.ExternalJwtAuthenticationConfig.RedirectUrl
: string.Empty;

return res.AsJson(new { Schemes = enabledSchemes, RedirectUrl = redirectUrl });
}

/// <summary>
Expand Down
26 changes: 20 additions & 6 deletions CometServer/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ namespace CometServer
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;

Expand Down Expand Up @@ -197,9 +198,9 @@ private static void SetUpAuthentication(IServiceCollection services, IConfigurat
throw new ConfigurationErrorsException("At least one authentication must be enabled");
}

if (isLocalJwtBearerEnabled && isExternalJwtBearerEnabled)
if (isExternalJwtBearerEnabled && (isBasicAuthEnabled || isLocalJwtBearerEnabled))
{
throw new ConfigurationErrorsException("Both local and external JWT Bearer authentication is enabled, only one may be enabled");
throw new ConfigurationErrorsException("Both local and external authentication are enabled, local one is not supported while external authentication is enabled");
}

var authenticationBuilder = services
Expand Down Expand Up @@ -311,6 +312,13 @@ private static void SetUpAuthentication(IServiceCollection services, IConfigurat
throw new ConfigurationErrorsException($"Invalid value for Authentication:ExternalJwtBearer:PersonIdentifierPropertyKind," +
$" should be one of: {string.Join(", ",Enum.GetValues<PersonIdentifierPropertyKind>())}");
}

var redirectUrl = configuration["Authentication:ExternalJwtBearer:RedirectUrl"];

if (string.IsNullOrEmpty(redirectUrl))
{
throw new ConfigurationErrorsException("The Authentication:ExternalJwtBearer:RedirectUrl setting must be available");
}

authenticationBuilder.AddExternalJwtBearerAuthentication(configure: options =>
{
Expand All @@ -322,12 +330,18 @@ private static void SetUpAuthentication(IServiceCollection services, IConfigurat
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = false,
SignatureValidator = (token, parameters) => new JsonWebToken(token),
ValidAudience = validAudience,
ValidIssuer = validIssuer
ValidIssuer = validIssuer,
SignatureValidator = (token, _) => new JsonWebToken(token)
};
}
);
});

var pluginInjector = new AuthenticationPluginInjector(new NullLogger<AuthenticationPluginInjector>());

if (!pluginInjector.Connectors.Any(x => x.Name == "CDP4ExternalJwtAuthentication" && x.Properties.IsEnabled))
{
throw new ConfigurationErrorsException("External JWT Authentication plugin is not present, please contact administrator to include Enterprise Edition plugins.");
}
}
else
{
Expand Down
9 changes: 5 additions & 4 deletions CometServer/appsettings.Development.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,23 @@
},
"Authentication": {
"Basic": {
"IsEnabled": true
"IsEnabled": false
},
"LocalJwtBearer": {
"IsEnabled": true,
"IsEnabled": false,
"ValidIssuer": "CDP4-COMET",
"ValidAudience": "localhost:5000",
"SymmetricSecurityKey": "needs-to-be-updated-with-a-secret",
"TokenExpirationMinutes": 150
},
"ExternalJwtBearer": {
"IsEnabled": false,
"IsEnabled": true,
"ValidIssuer": "http://localhost:8080/realms/CDP4COMET",
"ValidAudience": "account",
"Authority": "http://localhost:8080/realms/CDP4COMET",
"IdentifierClaimName": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname",
"PersonIdentifierPropertyKind": "ShortName"
"PersonIdentifierPropertyKind": "ShortName",
"RedirectUrl": "localhost:8080/realms/CDP4COMET/protocol/openid-connect/auth?response_type=token&client_id=cdp4-comet-server&scope=openid_offline_access&redirect_url=http://localhost:5000"
}
},
"Serilog": {
Expand Down

0 comments on commit fe2d7f8

Please sign in to comment.