22using HotChocolate . Execution . Configuration ;
33using PhantomDave . BankTracking . Api . Services ;
44using PhantomDave . BankTracking . Data . Extensions ;
5+ using Microsoft . AspNetCore . Authentication . JwtBearer ;
6+ using Microsoft . IdentityModel . Tokens ;
7+ using System . Text ;
8+ using Microsoft . Extensions . DependencyInjection ;
9+ using HotChocolate . AspNetCore ;
10+ using HotChocolate . Authorization ;
511
612namespace PhantomDave . BankTracking . Api ;
713
@@ -15,7 +21,46 @@ public static void Main(string[] args)
1521 ?? throw new InvalidOperationException ( "Connection string 'DefaultConnection' not configured." ) ;
1622 builder . Services . AddDataAccess ( connectionString ) ;
1723
24+ // Register services
1825 builder . Services . AddScoped < AccountService > ( ) ;
26+ builder . Services . Configure < JwtSettings > ( builder . Configuration . GetSection ( "Jwt" ) ) ;
27+ builder . Services . AddSingleton < IJwtTokenService , JwtTokenService > ( ) ;
28+
29+ // Authentication & Authorization
30+ var jwtSection = builder . Configuration . GetSection ( "Jwt" ) ;
31+ var secret = jwtSection [ "Secret" ] ;
32+ if ( string . IsNullOrWhiteSpace ( secret ) )
33+ {
34+ throw new InvalidOperationException ( "JWT Secret is not configured. Please set Jwt:Secret in configuration." ) ;
35+ }
36+ var issuer = jwtSection [ "Issuer" ] ;
37+ var audience = jwtSection [ "Audience" ] ;
38+ var key = new SymmetricSecurityKey ( Encoding . UTF8 . GetBytes ( secret ) ) ;
39+
40+ builder . Services
41+ . AddAuthentication ( options =>
42+ {
43+ options . DefaultAuthenticateScheme = JwtBearerDefaults . AuthenticationScheme ;
44+ options . DefaultChallengeScheme = JwtBearerDefaults . AuthenticationScheme ;
45+ } )
46+ . AddJwtBearer ( options =>
47+ {
48+ options . RequireHttpsMetadata = false ; // enable HTTPS in production
49+ options . SaveToken = true ;
50+ options . TokenValidationParameters = new TokenValidationParameters
51+ {
52+ ValidateIssuer = ! string . IsNullOrWhiteSpace ( issuer ) ,
53+ ValidIssuer = issuer ,
54+ ValidateAudience = ! string . IsNullOrWhiteSpace ( audience ) ,
55+ ValidAudience = audience ,
56+ ValidateIssuerSigningKey = true ,
57+ IssuerSigningKey = key ,
58+ ValidateLifetime = true ,
59+ ClockSkew = TimeSpan . FromMinutes ( 1 )
60+ } ;
61+ } ) ;
62+
63+ builder . Services . AddAuthorization ( ) ;
1964
2065 builder . Services . AddCors ( options =>
2166 {
@@ -29,6 +74,7 @@ public static void Main(string[] args)
2974
3075 var graphqlBuilder = builder . Services
3176 . AddGraphQLServer ( )
77+ . AddAuthorization ( )
3278 . AddQueryType ( )
3379 . AddMutationType ( ) ;
3480
@@ -40,6 +86,10 @@ public static void Main(string[] args)
4086 // Abilita CORS prima del mapping GraphQL
4187 app . UseCors ( ) ;
4288
89+ // Authentication/Authorization middleware
90+ app . UseAuthentication ( ) ;
91+ app . UseAuthorization ( ) ;
92+
4393 app . MapGraphQL ( ) ;
4494
4595 app . RunWithGraphQLCommands ( args ) ;
0 commit comments