diff --git a/.gitignore b/.gitignore
index 785fcf0..c1aab2e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,7 @@ msbuild.wrn
.vscode/
.vs/
.idea/
+appsettings.development.json
# Cache
*.swp
diff --git a/AdvancedSystems.Backend/AdvancedSystems.Backend.csproj b/AdvancedSystems.Backend/AdvancedSystems.Backend.csproj
index b64ac70..5b3ce3e 100644
--- a/AdvancedSystems.Backend/AdvancedSystems.Backend.csproj
+++ b/AdvancedSystems.Backend/AdvancedSystems.Backend.csproj
@@ -13,6 +13,7 @@
+
diff --git a/AdvancedSystems.Backend/DependencyInjection/ServiceCollectionExtensions.cs b/AdvancedSystems.Backend/DependencyInjection/ServiceCollectionExtensions.cs
index 9195562..da26990 100644
--- a/AdvancedSystems.Backend/DependencyInjection/ServiceCollectionExtensions.cs
+++ b/AdvancedSystems.Backend/DependencyInjection/ServiceCollectionExtensions.cs
@@ -3,6 +3,7 @@
using AdvancedSystems.Backend.Core.Validators;
using AdvancedSystems.Backend.Interfaces;
+using AdvancedSystems.Backend.Models;
using AdvancedSystems.Backend.Models.Settings;
using AdvancedSystems.Backend.Services;
using AdvancedSystems.Backend.Services.HealthChecks;
@@ -12,6 +13,7 @@
using Asp.Versioning;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.Http;
@@ -21,6 +23,7 @@
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
+using Microsoft.IdentityModel.Tokens;
using Swashbuckle.AspNetCore.SwaggerGen;
@@ -86,9 +89,53 @@ public static IServiceCollection AddCachingService(this IServiceCollection servi
}
#endregion
-
+
+ #region Authentication and Authorization
+
+ public static IServiceCollection AddJwtAuth(this IServiceCollection services)
+ {
+ var authBuilder = services.AddAuthentication(options =>
+ {
+ options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
+ options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
+ options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
+ });
+
+ authBuilder.AddJwtBearer(options =>
+ {
+ options.TokenValidationParameters = new TokenValidationParameters
+ {
+ // TODO: configure token validation parameters properly
+ IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes("secret")),
+ ValidateIssuerSigningKey = true,
+ ValidateLifetime = true,
+ ValidIssuer = "issuer",
+ ValidAudience = "audience",
+ ValidateIssuer = true,
+ ValidateAudience = true,
+ };
+ });
+
+ services.AddJwtPolicy();
+
+ return services;
+ }
+
+ public static IServiceCollection AddJwtPolicy(this IServiceCollection services)
+ {
+ return services.AddAuthorization(options =>
+ {
+ options.AddPolicy(Roles.Admin, policy =>
+ {
+ policy.RequireClaim(CustomClaim.IsAdmin, "true").RequireAuthenticatedUser();
+ });
+ });
+ }
+
+ #endregion
+
#region Health Checks
-
+
public static IServiceCollection AddBackendHealthChecks(this IServiceCollection services)
{
services.AddSingleton();
@@ -126,12 +173,16 @@ public static IServiceCollection AddBackendDocumentation(this IServiceCollection
{
var settings = configuration.GetRequiredSection(nameof(AppSettings)).Get();
- services.AddApiVersioning(option => {
+ var apiVersionBuilder = services.AddApiVersioning(option => {
option.DefaultApiVersion = new ApiVersion(settings!.DefaultApiVersion);
option.AssumeDefaultVersionWhenUnspecified = true;
option.ReportApiVersions = true;
option.ApiVersionReader = new MediaTypeApiVersionReader("api-version");
- }).AddMvc().AddApiExplorer();
+ });
+
+ apiVersionBuilder
+ .AddMvc()
+ .AddApiExplorer();
services.TryAdd(ServiceDescriptor.Transient, ConfigureSwaggerOptions>());
services.AddSwaggerGen(option => option.OperationFilter());
diff --git a/AdvancedSystems.Backend/DependencyInjection/Startup.cs b/AdvancedSystems.Backend/DependencyInjection/Startup.cs
index 7e844bf..f0f12cf 100644
--- a/AdvancedSystems.Backend/DependencyInjection/Startup.cs
+++ b/AdvancedSystems.Backend/DependencyInjection/Startup.cs
@@ -54,6 +54,8 @@ public static IServiceCollection ConfigureServices(this IServiceCollection servi
options.LowercaseUrls = true;
});
+ services.AddJwtAuth();
+
services.AddControllers();
services.AddBackendHealthChecks();
@@ -85,6 +87,9 @@ public static void Configure(this WebApplication app, IHostEnvironment environme
app.UseHsts();
}
+ app.UseAuthentication();
+ app.UseAuthorization();
+
app.UseHttpsRedirection();
app.UseStatusCodePages();
app.UseExceptionHandler();
diff --git a/AdvancedSystems.Backend/Models/CustomClaim.cs b/AdvancedSystems.Backend/Models/CustomClaim.cs
new file mode 100644
index 0000000..e59ca1c
--- /dev/null
+++ b/AdvancedSystems.Backend/Models/CustomClaim.cs
@@ -0,0 +1,6 @@
+namespace AdvancedSystems.Backend.Models;
+
+public static class CustomClaim
+{
+ public static readonly string IsAdmin = "is_admin";
+}
diff --git a/AdvancedSystems.Backend/Models/Roles.cs b/AdvancedSystems.Backend/Models/Roles.cs
new file mode 100644
index 0000000..00b0760
--- /dev/null
+++ b/AdvancedSystems.Backend/Models/Roles.cs
@@ -0,0 +1,6 @@
+namespace AdvancedSystems.Backend.Models;
+
+public static class Roles
+{
+ public static readonly string Admin = "Admin";
+}
diff --git a/AdvancedSystems.Backend/appsettings.json b/AdvancedSystems.Backend/appsettings.json
index 886f7f2..a398b8f 100644
--- a/AdvancedSystems.Backend/appsettings.json
+++ b/AdvancedSystems.Backend/appsettings.json
@@ -2,6 +2,11 @@
"AppSettings": {
"DefaultApiVersion": 1.0
},
+ "Jwt": {
+ "Key": "",
+ "Issuer": "",
+ "Audience": ""
+ },
"NLog": {
"extensions": [
{