11using System . Data ;
2+ using System . Net . Http . Headers ;
3+ using System . Security . Cryptography ;
24using System . Text ;
35using System . Text . Json ;
46using System . Text . Json . Serialization ;
7+ using System . Threading . Tasks ;
58using Fragment . NetSlum . Core . CommandBus ;
69using Fragment . NetSlum . Networking . Extensions ;
710using Fragment . NetSlum . Networking . Stores ;
811using Fragment . NetSlum . Persistence ;
912using Fragment . NetSlum . Persistence . Extensions ;
1013using Fragment . NetSlum . Persistence . Interceptors ;
1114using Fragment . NetSlum . Persistence . Listeners ;
15+ using Fragment . NetSlum . Server . Authentication ;
16+ using Fragment . NetSlum . Server . Authentication . Configuration ;
1217using Fragment . NetSlum . Server . Converters ;
1318using Fragment . NetSlum . Server . Servers ;
1419using Fragment . NetSlum . Server . Services ;
1520using Fragment . NetSlum . TcpServer ;
1621using HealthChecks . UI . Client ;
22+ using Microsoft . AspNetCore . Authentication . JwtBearer ;
1723using Microsoft . AspNetCore . Builder ;
1824using Microsoft . AspNetCore . Diagnostics . HealthChecks ;
1925using Microsoft . EntityFrameworkCore ;
2026using Microsoft . Extensions . Configuration ;
2127using Microsoft . Extensions . DependencyInjection ;
2228using Microsoft . Extensions . Hosting ;
29+ using Microsoft . Extensions . Options ;
30+ using Microsoft . IdentityModel . Tokens ;
2331using Serilog ;
2432
2533namespace Fragment . NetSlum . Server ;
@@ -40,7 +48,8 @@ public void ConfigureServices(IServiceCollection services)
4048 // Add failsafe to ensure the database is never executed on the original one
4149 if ( connectionString ! . Contains ( "Database=fragment;" ) )
4250 {
43- throw new ConstraintException ( "Auto-migrations have been disabled. The connection string contains the old database information!" ) ;
51+ throw new ConstraintException (
52+ "Auto-migrations have been disabled. The connection string contains the old database information!" ) ;
4453 }
4554
4655 services
@@ -69,13 +78,49 @@ public void ConfigureServices(IServiceCollection services)
6978 . AddDbContextCheck < FragmentContext > ( )
7079 . AddPrivateMemoryHealthCheck ( 2147483648 )
7180 . AddProcessAllocatedMemoryHealthCheck ( 2048 )
72- ;
81+ ;
82+
83+ services . Configure < DiscordAuthOptions > ( Configuration . GetSection ( "Authentication" ) ) ;
84+
85+ services . AddAuthentication ( )
86+ . AddJwtBearer ( JwtBearerDefaults . AuthenticationScheme ) ;
87+
88+ services . AddOptions < JwtBearerOptions > ( JwtBearerDefaults . AuthenticationScheme )
89+ . Configure < IOptions < DiscordAuthOptions > > ( ( options , discordOptions ) =>
90+ {
91+ options . TokenHandlers . Clear ( ) ;
92+ options . TokenHandlers . Add ( new DiscordJwtTokenHandler ( discordOptions ) ) ;
93+
94+ options . Events = new JwtBearerEvents
95+ {
96+ // Allow the JWT policy to accept the token from either the Authorization header, or the 'token' cookie
97+ // supplied in the request
98+ OnMessageReceived = context =>
99+ {
100+ context . Token = context . HttpContext . Request . Headers . TryGetValue ( "Authorization" , out var bearerToken )
101+ ? AuthenticationHeaderValue . Parse ( bearerToken . ToString ( ) ) . Parameter
102+ : context . HttpContext . Request . Cookies [ "netslum-token" ] ;
103+
104+ return Task . CompletedTask ;
105+ } ,
106+ } ;
107+
108+ options . MapInboundClaims = true ;
109+ options . IncludeErrorDetails = true ;
110+ options . TokenValidationParameters = new TokenValidationParameters
111+ {
112+ RequireSignedTokens = true ,
113+ ValidateAudience = false ,
114+ ValidateIssuer = false ,
115+ ValidateIssuerSigningKey = true ,
116+ IncludeTokenOnFailedValidation = true ,
117+ ValidateLifetime = true ,
118+ IssuerSigningKey = new SymmetricSecurityKey ( Encoding . UTF8 . GetBytes ( discordOptions . Value . JwtSecret ) ) ,
119+ } ;
120+ } ) ;
73121
74122 // Register command bus
75- services . AddMediator ( opt =>
76- {
77- opt . ServiceLifetime = ServiceLifetime . Transient ;
78- } ) ;
123+ services . AddMediator ( opt => { opt . ServiceLifetime = ServiceLifetime . Transient ; } ) ;
79124 services . AddScoped < ICommandBus , MediatorCommandBus > ( ) ;
80125
81126 services . AddOpenApiDocument ( doc =>
@@ -99,19 +144,30 @@ public void ConfigureServices(IServiceCollection services)
99144
100145 public void Configure ( IApplicationBuilder app , IHostEnvironment env )
101146 {
147+ app . UseSerilogRequestLogging ( o =>
148+ {
149+ o . MessageTemplate =
150+ "HTTP [{ClientIp}] {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms" ;
151+ o . IncludeQueryInRequestPath = true ;
152+ } ) ;
153+
102154 app . UseRouting ( ) ;
103155 app . UseCors ( opt =>
104156 {
157+ opt . SetIsOriginAllowedToAllowWildcardSubdomains ( ) ;
105158 opt . AllowAnyHeader ( ) ;
106159 opt . AllowAnyMethod ( ) ;
107- opt . AllowAnyOrigin ( ) ;
160+ opt . WithOrigins ( Configuration . GetValue < string > ( "AllowedOrigins" ) ? . Split ( "," ) ?? [ "*" ] )
161+ . AllowCredentials ( ) ;
108162 } ) ;
109163
110164 app . UseHealthChecks ( "/api/health" , new HealthCheckOptions
111165 {
112166 ResponseWriter = UIResponseWriter . WriteHealthCheckUIResponse ,
113167 } ) ;
114168
169+ app . UseAuthentication ( ) ;
170+ app . UseAuthorization ( ) ;
115171 app . UseStaticFiles ( ) ;
116172 app . UseOpenApi ( ) ;
117173 app . UseSwaggerUi ( opt =>
0 commit comments