@@ -65,6 +65,8 @@ public class CrudApiConfiguration
65
65
{
66
66
public string ApiFile { get ; set ; } = "api.json" ;
67
67
public string BaseUrl { get ; set ; } = string . Empty ;
68
+ [ JsonPropertyName ( "enableCors" ) ]
69
+ public bool EnableCORS { get ; set ; } = true ;
68
70
public string DataFile { get ; set ; } = string . Empty ;
69
71
public IEnumerable < CrudApiAction > Actions { get ; set ; } = [ ] ;
70
72
[ System . Text . Json . Serialization . JsonConverter ( typeof ( JsonStringEnumConverter ) ) ]
@@ -165,6 +167,13 @@ protected virtual Task OnRequestAsync(object? sender, ProxyRequestArgs e)
165
167
return Task . CompletedTask ;
166
168
}
167
169
170
+ if ( IsCORSPreflightRequest ( request ) && _configuration . EnableCORS )
171
+ {
172
+ SendEmptyResponse ( HttpStatusCode . NoContent , e . Session ) ;
173
+ Logger . LogRequest ( "CORS preflight request" , MessageType . Mocked , new LoggingContext ( e . Session ) ) ;
174
+ return Task . CompletedTask ;
175
+ }
176
+
168
177
if ( ! AuthorizeRequest ( e ) )
169
178
{
170
179
SendUnauthorizedResponse ( e . Session ) ;
@@ -193,6 +202,35 @@ protected virtual Task OnRequestAsync(object? sender, ProxyRequestArgs e)
193
202
return Task . CompletedTask ;
194
203
}
195
204
205
+ private static bool IsCORSPreflightRequest ( Request request )
206
+ {
207
+ return request . Method == "OPTIONS" &&
208
+ request . Headers . Any ( h => h . Name . Equals ( "Origin" , StringComparison . OrdinalIgnoreCase ) ) ;
209
+ }
210
+
211
+ private void AddCORSHeaders ( Request request , List < HttpHeader > headers )
212
+ {
213
+ var origin = request . Headers . FirstOrDefault ( h => h . Name . Equals ( "Origin" , StringComparison . OrdinalIgnoreCase ) ) ? . Value ;
214
+ if ( string . IsNullOrEmpty ( origin ) )
215
+ {
216
+ return ;
217
+ }
218
+
219
+ headers . Add ( new HttpHeader ( "access-control-allow-origin" , origin ) ) ;
220
+
221
+ if ( _configuration . EntraAuthConfig is not null )
222
+ {
223
+ headers . Add ( new HttpHeader ( "access-control-allow-headers" , "authorization" ) ) ;
224
+ }
225
+
226
+ var methods = string . Join ( ", " , _configuration . Actions
227
+ . Where ( a => a . Method is not null )
228
+ . Select ( a => a . Method )
229
+ . Distinct ( ) ) ;
230
+
231
+ headers . Add ( new HttpHeader ( "access-control-allow-methods" , methods ) ) ;
232
+ }
233
+
196
234
private bool AuthorizeRequest ( ProxyRequestArgs e , CrudApiAction ? action = null )
197
235
{
198
236
var authType = action is null ? _configuration . Auth : action . Auth ;
@@ -304,12 +342,12 @@ private static bool HasPermission(string permission, string permissionString)
304
342
return permissions . Contains ( permission , StringComparer . OrdinalIgnoreCase ) ;
305
343
}
306
344
307
- private static void SendUnauthorizedResponse ( SessionEventArgs e )
345
+ private void SendUnauthorizedResponse ( SessionEventArgs e )
308
346
{
309
347
SendJsonResponse ( "{\" error\" :{\" message\" :\" Unauthorized\" }}" , HttpStatusCode . Unauthorized , e ) ;
310
348
}
311
349
312
- private static void SendNotFoundResponse ( SessionEventArgs e )
350
+ private void SendNotFoundResponse ( SessionEventArgs e )
313
351
{
314
352
SendJsonResponse ( "{\" error\" :{\" message\" :\" Not found\" }}" , HttpStatusCode . NotFound , e ) ;
315
353
}
@@ -327,25 +365,19 @@ private static string ReplaceParams(string query, IDictionary<string, string> pa
327
365
return result ;
328
366
}
329
367
330
- private static void SendEmptyResponse ( HttpStatusCode statusCode , SessionEventArgs e )
368
+ private void SendEmptyResponse ( HttpStatusCode statusCode , SessionEventArgs e )
331
369
{
332
370
var headers = new List < HttpHeader > ( ) ;
333
- if ( e . HttpClient . Request . Headers . Any ( h => h . Name == "Origin" ) )
334
- {
335
- headers . Add ( new HttpHeader ( "access-control-allow-origin" , "*" ) ) ;
336
- }
371
+ AddCORSHeaders ( e . HttpClient . Request , headers ) ;
337
372
e . GenericResponse ( "" , statusCode , headers ) ;
338
373
}
339
374
340
- private static void SendJsonResponse ( string body , HttpStatusCode statusCode , SessionEventArgs e )
375
+ private void SendJsonResponse ( string body , HttpStatusCode statusCode , SessionEventArgs e )
341
376
{
342
377
var headers = new List < HttpHeader > {
343
378
new ( "content-type" , "application/json; charset=utf-8" )
344
379
} ;
345
- if ( e . HttpClient . Request . Headers . Any ( h => h . Name == "Origin" ) )
346
- {
347
- headers . Add ( new HttpHeader ( "access-control-allow-origin" , "*" ) ) ;
348
- }
380
+ AddCORSHeaders ( e . HttpClient . Request , headers ) ;
349
381
e . GenericResponse ( body , statusCode , headers ) ;
350
382
}
351
383
0 commit comments