How do you secure a Web API?

Web API & REST Security Advanced 3–5 Yrs5+ Yrs Scenario 1 min read

Quick Answer

Layered: HTTPS everywhere; authenticate every request (JWT bearer, OAuth2, or API keys for service-to-service); authorize per endpoint with policies; validate and bind to DTOs to stop over-posting and injection; add rate limiting; lock down CORS to known origins; return generic errors (no stack traces); and keep dependencies patched.

I think about it in layers. Transport: HTTPS and HSTS. Authentication: every request carries a credential — JWT bearer for users, client-credentials OAuth or signed keys for other services — and I validate issuer, audience and expiry, not just the signature. Authorization: policies per endpoint, and resource-level checks so a user can't fetch someone else's record by changing the id. Input: validate, bind to DTOs not entities to prevent over-posting, and let EF or parameters handle SQL so there's no injection. Then rate limiting to blunt abuse, a strict CORS allow-list, generic ProblemDetails errors with no stack traces, secrets in a vault, and keeping packages patched.

  • Transport — UseHttpsRedirection + HSTS; TLS terminated at the edge is fine.
  • AuthN — JWT bearer for users/SPAs, client-credentials OAuth or signed API keys for machine callers. Validate issuer, audience, lifetime, signature.
  • AuthZ — [Authorize(Policy = ...)], resource-based checks for “can this user touch this record”.
  • Input — model validation, DTOs (not entities), parameterised queries / EF (no string-concatenated SQL), size limits on bodies and uploads.
  • Abuse — rate limiting (AddRateLimiter), request throttling, and idempotency keys on unsafe operations.
  • CORS — an explicit allow-list of origins; never AllowAnyOrigin with credentials.
  • Output — ProblemDetails error bodies with no internal detail; security headers.
  • Ops — secrets in a vault, logging without PII/tokens, dependency scanning.