AntiforgeryToken C# .NET - 400 Bad Request #163166
Replies: 10 comments 7 replies
-
|
Problem:
Option A: Skip Antiforgery for APIs (Recommended for APIs that are authenticated differently, e.g., via JWT) services.AddControllers(); // no antiforgery token required Or exclude API controllers: Option B: Generate and use antiforgery tokens correctly Get the token from a GET endpoint (which calls IAntiforgery.GetAndStoreTokens()): This sets the antiforgery cookie and returns the token. In Swagger or Postman: Quick Fix for Swagger Testing: public void Configure(IApplicationBuilder app, IWebHostEnvironment env) } Or, apply [IgnoreAntiforgeryToken] on controller methods when testing. Summary:
|
Beta Was this translation helpful? Give feedback.
-
|
Hi Eric, thanks for the reply and extra info — I see you're already generating the token correctly and adding it in Swagger, which helps narrow it down. One common issue (even if you add XSRF-TOKEN header) is that Swagger UI by default does not send the antiforgery cookie (.AspNetCore.Antiforgery.*) along with the request — and antiforgery checks require both the token in header and the corresponding cookie on the same request. So even if you manually add the header, if the cookie is missing or not passed with the request (which usually happens in Swagger), the server will return 400. A few options to try: 1️⃣ Test with browser + front-end — since the browser handles cookies automatically, this often works even if Swagger doesn't. 2️⃣ Use a tool like Postman — you can manually set both the cookie and header there and verify that your antiforgery setup works. 3️⃣ Swagger config workaround — if you want to test from Swagger, you would need to either: Customize Swagger UI to support sending cookies Or bypass antiforgery on Swagger routes for testing (as I showed earlier). Summary: It’s likely not an issue in your antiforgery generation logic — it’s a limitation of Swagger testing with cookies. The real test would be to verify with your front-end or Postman where cookies flow correctly. If you want, I can also share an example of customizing Swagger UI to send cookies if you'd like to go that route |
Beta Was this translation helpful? Give feedback.
-
|
Hi Eric — thanks again for the details, now it's very clear what’s happening. 👍 Quick recap: ✅ You are sending the header X-XSRF-TOKEN And that’s why POST fails in Swagger — antiforgery validation on the server requires both the cookie + header, not just the header. How to fix it in Swagger? — You need Swagger UI to send cookies. Unfortunately, the default Swashbuckle Swagger UI for .NET does not enable this — you have to add it yourself when configuring Swagger UI. app.UseSwaggerUI(c => }); Why this works: Summary: ✅ Your antiforgery setup is correct Once you add that — Swagger POST/PUT/DELETE should start working without needing [IgnoreAntiforgeryToken]. |
Beta Was this translation helpful? Give feedback.
-
|
Hi Eric — I get what you mean — but here’s why ASP.NET Core antiforgery does require both the header and the cookie, by design: ✅ The header (X-XSRF-TOKEN) proves that the client knows the token ASP.NET Core antiforgery system always matches: token in header == token in cookie That’s how it protects against CSRF attacks — if only a header is sent (no cookie), the framework will reject the request with 400. This is the reason it works in browsers (which send both automatically), but fails in Swagger UI (which by default sends only the header, not the cookie). How can you confirm this? Microsoft docs say this: "For security, ASP.NET Core validates that the token received in the request header matches the antiforgery cookie stored on the client." (See: Antiforgery in ASP.NET Core) |
Beta Was this translation helpful? Give feedback.
-
|
Hi Eric — here’s the full picture: ✅ You do NOT need to define the cookie in AddSecurityDefinition — that won’t make Swagger send cookies. ✅ You need to configure Swagger UI to send cookies — and that is done by setting: How to do this? — Depends on your Swashbuckle version: 🔹 For Swashbuckle.AspNetCore 6.x: app.UseSwaggerUI(c => }); 🔹 For Swashbuckle.AspNetCore 7.x (and above): }); Once you do this — now Swagger will send both: ✅ Your X-XSRF-TOKEN header (you already have this!) And then POST/PUT/DELETE will pass antiforgery validation If you tell me which version you use — I can give you an exact working example . |
Beta Was this translation helpful? Give feedback.
-
|
If you’re using Swashbuckle 8.x — then the old: won’t work anymore — because in Swashbuckle 8.x, the API changed. In Swashbuckle 8.x, you should now use: So in short: ✅ You are doing everything right |
Beta Was this translation helpful? Give feedback.
-
|
Just check which Swashbuckle.AspNetCore version you are actually using — you can check in: |
Beta Was this translation helpful? Give feedback.
-
|
So you’re using Swashbuckle.AspNetCore 6.7 — in this version, the correct way is: }); Tip: Also make sure that when you call your POST request — your browser has the correct: |
Beta Was this translation helpful? Give feedback.
-
|
🕒 Discussion Activity Reminder 🕒 This Discussion has been labeled as dormant by an automated system for having no activity in the last 60 days. Please consider one the following actions: 1️⃣ Close as Out of Date: If the topic is no longer relevant, close the Discussion as 2️⃣ Provide More Information: Share additional details or context — or let the community know if you've found a solution on your own. 3️⃣ Mark a Reply as Answer: If your question has been answered by a reply, mark the most helpful reply as the solution. Note: This dormant notification will only apply to Discussions with the Thank you for helping bring this Discussion to a resolution! 💬 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Select Topic Area
Question
Body
Hi everyone, Im trying to implement the antiforgery token in my C# .NET application and I have already made the Startup implementation but when I try to test any POST API, Im trying at this moment only at swagger, I get a 400 bad request. Im using the:
_ = services.AddControllersWithViews(options => options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));to add the autovalidate atribute on the controllers.Also adding the X-XSRF-TOKEN in the headers of the request but always getting Bad request, but when I put
[IgnoreAntiforgeryToken]Im able to try any type o Request.There is somebody that could help or had the same "issue" and how had fixed? Searched a lot on the internet but everything I saw I have already did, getting out of ideas.
Beta Was this translation helpful? Give feedback.
All reactions