fix(security): enforce explicit api authorization
CI and Deploy / test (push) Failing after 1m10s
CI and Deploy / deploy (push) Has been skipped

Authentication relied on a fallback policy gated on Auth:Require, which defaults
to false. Five user-owned controllers carried no [Authorize] of their own, so a
deployment that lost that flag would have served tenant data anonymously:
JobApplications, Companies, Correspondence, Rules and JobImport. All five now
declare [Authorize(AuthenticationSchemes = "local")] explicitly.

This does not affect local development, which already sets Auth:Require=true in
appsettings.Development.json — the gap was only ever in a production
configuration that omitted the flag.

Added a reflection test over every controller in the assembly so a new one
cannot ship unprotected by accident. A controller passes if the class requires
authorization, or if every action declares its own [Authorize] or
[AllowAnonymous] — the shape AuthController and TwoFactorController need, since
login and register must stay anonymous while the rest must not. Public endpoints
are an explicit allow-list, so making something anonymous is now a deliberate
edit rather than an omission.

That test found one real gap: AuthController.Logout declared neither attribute.
It is now explicitly [AllowAnonymous] — it only clears the caller's own session
cookies and leaks nothing, and requiring authentication would leave a user whose
token had already expired unable to sign out.

Also pinned: admin controllers require the Admin role rather than merely a
signed-in user, and PublicCvController stays anonymous so shared CV links keep
working.

384 backend tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
cesnimda
2026-07-19 17:27:27 +02:00
parent a3735299ec
commit c0bf69ad56
7 changed files with 159 additions and 4 deletions
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using JobTrackerApi.Data;
@@ -15,7 +16,11 @@ using static JobTrackerApi.Services.JobApplicationHelpers;
namespace JobTrackerApi.Controllers
{
[ApiController]
// Explicitly authorized. These endpoints are all tenant-scoped user data, so they must not
// depend on the Auth:Require fallback policy being switched on: a deployment that lost that flag
// would otherwise serve them anonymously. docs/production-readiness-review.md.
[Route("api/jobapplications")]
[Authorize(AuthenticationSchemes = "local")]
public class JobApplicationsController : ControllerBase
{
private readonly JobTrackerContext _db;