Table of Contents

Class AuthController

Namespace
SEBT.Portal.Api.Controllers.Auth
Assembly
SEBT.Portal.Api.dll

Controller for handling authorization status checks, token refresh, and logout. The portal JWT is stored in an HttpOnly cookie (see AuthCookies); endpoints that issue a new session write to the cookie and return non-sensitive metadata only.

[ApiController]
[Route("api/auth")]
public class AuthController : ControllerBase
Inheritance
object
ControllerBase
AuthController

Constructors

AuthController(ILogger<AuthController>, IOptions<JwtSettings>)

Controller for handling authorization status checks, token refresh, and logout. The portal JWT is stored in an HttpOnly cookie (see AuthCookies); endpoints that issue a new session write to the cookie and return non-sensitive metadata only.

public AuthController(ILogger<AuthController> logger, IOptions<JwtSettings> jwtSettingsOptions)

Parameters

logger ILogger<AuthController>
jwtSettingsOptions IOptions<JwtSettings>

Methods

GetAuthorizationStatus()

Returns the caller's session info read from validated JWT claims. The JWT is carried in the HttpOnly session cookie; this endpoint exposes the non-sensitive claims the SPA needs for IAL gating, analytics, and UI state.

Anonymous callers (no cookie, or an expired/tampered/revoked session) get 200 with isAuthorized: false instead of a 401: the SPA probes this endpoint on every page load — including logged-out ones — so "not signed in" is an expected answer, not an error worth surfacing in logs and traces. Bearer authentication still runs first, so an invalid session cookie is still cleared (Set-Cookie) exactly as before.

[HttpGet("status")]
[AllowAnonymous]
[ProducesResponseType(typeof(AuthorizationStatusResponse), 200)]
public IActionResult GetAuthorizationStatus()

Returns

IActionResult

An OK result with the session info for the caller.

Logout(IOptionsSnapshot<OidcSettings>, IOidcExchangeService, ITokenDenylist, CancellationToken)

Revokes the surrendered session token's jti (best-effort) before clearing the local session cookie, then redirects to the IdP's end_session_endpoint (RP-Initiated Logout) when OIDC is configured, or to /login otherwise. The entire redirect chain is browser-level — no JavaScript processes the IdP logout URL, eliminating XSS as a vector for redirect tampering.

[HttpGet("logout")]
[AllowAnonymous]
[ProducesResponseType(302)]
public Task<IActionResult> Logout(IOptionsSnapshot<OidcSettings> oidcSettings, IOidcExchangeService oidcExchangeService, ITokenDenylist tokenDenylist, CancellationToken cancellationToken = default)

Parameters

oidcSettings IOptionsSnapshot<OidcSettings>
oidcExchangeService IOidcExchangeService
tokenDenylist ITokenDenylist
cancellationToken CancellationToken

Returns

Task<IActionResult>

RefreshToken(ICommandHandler<RefreshTokenCommand, string>)

Refreshes the session JWT for the authenticated user. The new token is returned via the HttpOnly session cookie; the response body carries no token.

[HttpPost("refresh")]
[Authorize]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(ErrorResponse), 400)]
[ProducesResponseType(typeof(ErrorResponse), 401)]
[ProducesResponseType(typeof(ErrorResponse), 404)]
[ProducesResponseType(typeof(ErrorResponse), 500)]
public Task<IActionResult> RefreshToken(ICommandHandler<RefreshTokenCommand, string> handler)

Parameters

handler ICommandHandler<RefreshTokenCommand, string>

The command handler for processing the token refresh.

Returns

Task<IActionResult>

204 No Content on success; the new session cookie is set on the response.