Une gestion d’erreur de son API .Net automatique via ses exceptions
...
Sommaire
Par défaut, il n’est pas autorisé de faire des requêtes entre une application qui est dans un domaine A vers une autre qui serait dans un domaine B (pour des raisons de sécurité, il y a plus de détails dans les sources).
Si vous avez un front qui tourne sur un serveur node localhost:4200 et votre backend .Net sur localhost:7248), les requêtes du front vers le back seront bloquées car ils sont dans des domaines différents (ils n’ont pas le même numéro de port).
Si vous n’autorisez pas les CORS dans votre application, vous aurez un message de ce type:
Techniquement, lorsque votre front va appeler votre backend .NET, il va avant tout faire un appel de type OPTION qu’on appelle le “preflight check”. En réponse, votre backend va indiquer quels autres domaines peuvent le solliciter et sur quelles routes.
On va simplement aller dans le fichier Program.cs
et définir une politique d’autorisation via le code suivant:
var myAllowSpecificOrigins = "_myAllowSpecificOrigins"; builder.Services.AddCors(options => { options.AddPolicy(name: myAllowSpecificOrigins, policy => { policy.WithOrigins("http://localhost:4200") .AllowAnyMethod() .AllowAnyHeader(); }); });
Dans mon cas, le front tournait sur « http://localhost:4200 » , il faut bien évidemment remplacer par l’adresse que vous souhaitez autoriser.
Note: J’ai mis les options AllowAnyMethod()
et AllowAnyHeader()
, vous pouvez évidemment être plus restrictif ! Exemple:
policy.WithOrigins("http://localhost:4200") .WithMethods("POST") .WithHeaders("Authorization");
Il faut ensuite appliquer cette politique en rajoutant dans votre fichier:
app.UseCors(myAllowSpecificOrigins);
Faites très attention à l’endroit où vous mettez cette ligne de code, elle doit suivre l’ordre de déclaration préconisé par .NET donc avant app.UseAuthentication()
ou app.UseResponseCaching()
si vous les utilisez. Voici l’ordre préconisé par .NET à l’heure actuelle pour être sûr de ne pas vous tromper !
using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using WebMiddleware.Data; var builder = WebApplication.CreateBuilder(args); var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found."); builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString)); builder.Services.AddDatabaseDeveloperPageExceptionFilter(); builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>(); builder.Services.AddRazorPages(); builder.Services.AddControllersWithViews(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseMigrationsEndPoint(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); // app.UseCookiePolicy(); app.UseRouting(); // app.UseRateLimiter(); // app.UseRequestLocalization(); // app.UseCors(); app.UseAuthentication(); app.UseAuthorization(); // app.UseSession(); // app.UseResponseCompression(); // app.UseResponseCaching(); app.MapRazorPages(); app.MapDefaultControllerRoute(); app.Run();
Si vous avez bien appliqué cette méthode vous ne devriez plus avoir d’erreur 🙂En regardant le preflight check dans le navigateur (la requête de type OPTION) dans l’onglet réseau, on voit bien qu’on a notre backend répond l’url supportée, avec la méthode et le header approprié (premier rectangle rouge sur la capture d’écran) et ça doit matcher avec les headers de la requête envoyée (2 autres rectangles).
Conseil: Si ça ne fonctionne pas, pensez bien à comparer les URL définies dans le header de la requête et de la réponse, on peut se faire avoir par un petit “/” à la fin d’une des deux url 😛
J’espère que vous avez toutes les clefs pour gérer correctement les CORS dans votre application .NET. Pour aller plus loin, n’hésitez pas à regarder nos sources 🙂
https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-8.0
On va voir comment avoir en quelques minutes des assertions qui vont vérifier les endpoints de notre API avec des scénarios de ce genre: Feature: Create a new account As a visitor, I can create an account to access the game Scenario: A visitor c...
Depuis .NET 9, le le support d’OpenAPI est directement inclus dans .NET et ne passe plus par les librairies Swagger par défaut (plus d’info sur ce choix ici si jamais ça vous intéresse). De façons simplifiée, la librairie Swashbuckle.AspNetCore.Sw...
Image prise sur Windows Central Historique Pour cet article je vais faire un mini REX sur l’écosystème de Microsoft pour les développeurs. J’ai commencé à travailler avec les technologies Microsoft vers 2016. Pour situer, Windows 10 devait avoir �...