# NFR Requirements — Unit 0: Backend Prerequisites ## NFR-U0-01: Security — httpOnly Cookie (SECURITY-12) - Refresh token MUST be stored in an httpOnly, Secure (request.IsHttps), SameSite=Strict cookie - Access token MUST NOT be returned in persistent storage; only in response body and in-memory on client - See `business-rules.md` BR-U0-02, BR-U0-03 for detailed cookie specification ## NFR-U0-02: Security — CORS (SECURITY-08) - CORS MUST use explicit origin allowlist from configuration — no wildcard origins - `AllowCredentials()` MUST be set to allow the refresh token cookie to be sent cross-origin - CORS middleware MUST be registered before `UseAuthentication` in the pipeline - An empty `AllowedOrigins` array in production configuration is a safe default (no SPA access) ## NFR-U0-03: Security — Rate Limiting (SECURITY-11) - The `POST /api/v1/auth/login` and `POST /api/v1/auth/refresh` endpoints MUST have rate limiting - **Implementation**: ASP.NET Core built-in `RateLimiter` middleware (available in .NET 7+) - **Policy**: Fixed window — max **5 requests per 1 minute per IP address** on login endpoint - **Policy**: Sliding window — max **20 requests per 1 minute per IP address** on refresh endpoint - Exceeded rate limit returns `429 Too Many Requests` - Rate limit headers (`Retry-After`) MUST be included in 429 responses - Configuration stored in `appsettings.json → RateLimiting` section ## NFR-U0-04: Reliability — Refresh Token Lifetime - Refresh token lifetime: **7 days** (unchanged from current default) - After expiry, the user must re-authenticate via the login page - Refresh token rotation is already implemented — each refresh issues a new token ## NFR-U0-05: Error Response Format (SECURITY-09, SECURITY-15) - ALL authentication error responses MUST use **RFC 9457 ProblemDetails** format: ```json { "type": "https://tools.ietf.org/html/rfc7235#section-3.1", "title": "Unauthorized", "status": 401, "detail": "Invalid credentials." } ``` - Error messages MUST be generic — do NOT reveal whether email or password was wrong - Error messages MUST NOT expose internal details (stack traces, exception types, DB details) - `asp-problem-details` behavior is already partially handled by `GlobalExceptionHandler`; auth-specific errors may need explicit `ProblemDetails` returns in `AuthController` ## NFR-U0-06: Maintainability - Rate limiting configuration (window size, request limits) stored in `appsettings.json` — configurable without code changes - CORS origins stored in `appsettings.json` — configurable per environment - No magic strings for cookie name or policy name — use constants ## NFR-U0-07: Test Coverage - Unit tests for `AuthController` must be updated to cover: - Cookie is set on successful login/refresh - Cookie is cleared on revoke - 401 returned when cookie is missing on refresh - Rate limit behavior (mock rate limiter) - Existing `AuthService` unit tests remain valid (service signature unchanged)