books/backend/Books.Api/Controllers/AuthController.cs
Nicolaj Hartmann 926085eeab Add OpenID Connect + API Key authentication
Backend:
- Cookie + OIDC + API Key authentication schemes
- ApiKeyAuthenticationHandler with SHA-256 validation and 24h cache
- AuthController with login/logout/profile endpoints
- API Key domain model (EventFlow aggregate, events, commands)
- ApiKeyReadModel and repository for key validation
- Database migration 002_ApiKeys.sql
- CORS configuration for frontend

Frontend:
- authService.ts for login/logout/profile API calls
- authStore.ts (Zustand) for user context state
- ProtectedRoute component for route guards
- Header updated with user display and logout
- GraphQL client with credentials: include

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 11:49:29 +01:00

41 lines
1.1 KiB
C#

using Books.Api.Authentication;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Books.Api.Controllers;
[Route("api")]
[ApiController]
public class AuthController : ControllerBase
{
[HttpGet("login")]
[Authorize]
public IActionResult Login([FromQuery] string? returnUrl)
{
// The [Authorize] attribute triggers the OIDC challenge if not authenticated.
// If we reach here, the user is authenticated - redirect back to the app.
return Redirect(returnUrl ?? "/");
}
[HttpGet("logout")]
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return Ok(new { message = "Logged out successfully" });
}
[HttpGet("profile")]
[Authorize]
public IActionResult Profile()
{
var userContext = User.GetUserContext();
if (userContext == null)
{
return Unauthorized();
}
return Ok(userContext);
}
}