diff --git a/Api.SeaHavenIndustries/Infrastructure/JwtAuthenticationRegistration.cs b/Api.SeaHavenIndustries/Infrastructure/JwtAuthenticationRegistration.cs
new file mode 100644
index 0000000..a69bbf1
--- /dev/null
+++ b/Api.SeaHavenIndustries/Infrastructure/JwtAuthenticationRegistration.cs
@@ -0,0 +1,41 @@
+using System.Text;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.IdentityModel.Tokens;
+
+namespace Api.SeaHavenIndustries.Infrastructure
+{
+ public static class JwtAuthenticationRegistration
+ {
+ ///
+ /// Registers bearer-token authentication as the default scheme. Program.cs and the
+ /// behavior tests both compose authentication through this method so the token
+ /// rules under test are the rules that run.
+ ///
+ public static IServiceCollection AddSeaHavenJwtAuthentication(this IServiceCollection services, IConfiguration configuration)
+ {
+ services.AddAuthentication(options =>
+ {
+ options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
+ options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
+ options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
+ })
+ .AddJwtBearer(options =>
+ {
+ options.SaveToken = true;
+ options.RequireHttpsMetadata = false;
+ options.TokenValidationParameters = new TokenValidationParameters()
+ {
+ ValidateIssuer = true,
+ ValidateAudience = true,
+ ValidAudience = configuration["JWT:ValidAudience"],
+ ValidIssuer = configuration["JWT:ValidIssuer"],
+ IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
+ configuration["JWT:Secret"]
+ ?? throw new InvalidOperationException("JWT:Secret configuration is required")))
+ };
+ });
+
+ return services;
+ }
+ }
+}
diff --git a/Api.SeaHavenIndustries/Program.cs b/Api.SeaHavenIndustries/Program.cs
index 0151543..99cfe30 100644
--- a/Api.SeaHavenIndustries/Program.cs
+++ b/Api.SeaHavenIndustries/Program.cs
@@ -5,15 +5,12 @@ using Api.SeaHavenIndustries.Middleware;
using Api.SeaHavenIndustries.Observability;
using Api.SeaHavenIndustries.Options;
using Data.SeaHavenIndustries;
-using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.EntityFrameworkCore;
-using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Sentry.AspNetCore;
using Sentry.Extensibility;
-using System.Text;
using SeaHaven.DataServices.DependencyInjection;
using SeaHaven.Services.DependencyInjection;
using SeaHaven.Services.Implementation;
@@ -143,27 +140,7 @@ builder.Services.AddOptions
-{
- options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
- options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
- options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
-})
-.AddJwtBearer(options =>
-{
- options.SaveToken = true;
- options.RequireHttpsMetadata = false;
- options.TokenValidationParameters = new TokenValidationParameters()
- {
- ValidateIssuer = true,
- ValidateAudience = true,
- ValidAudience = configuration["JWT:ValidAudience"],
- ValidIssuer = configuration["JWT:ValidIssuer"],
- IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
- configuration["JWT:Secret"]
- ?? throw new InvalidOperationException("JWT:Secret configuration is required")))
- };
-});
+builder.Services.AddSeaHavenJwtAuthentication(configuration);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{