bloc.core.auth_server#

Starlette wrapper that adds Microsoft Entra ID authentication to Boulder.

Architecture#

Boulder’s FastAPI app registers a SPA catch-all route /{full_path:path} that would swallow /auth/* paths if auth routes were added to the same FastAPI instance after the fact. The solution is a thin outer Starlette application that owns the /auth/* routes and mounts Boulder as a sub-application at /. Starlette matches explicit Route entries before the Mount fallback, so auth paths are always handled correctly.

Request flow:

Internet
  → SessionMiddleware  (reads / writes signed ``bloc_session`` cookie)
  → AuthMiddleware     (checks session; redirects to /auth/login if absent)
  → Starlette router
       /auth/login     → login()    [public]
       /auth/callback  → callback() [public]
       /auth/logout    → logout()   [public]
       /auth/me        → me()       [public]
       /               → Boulder FastAPI app (all other paths)

Usage:

import boulder.api.main as _api_main
from bloc.core.auth_server import wrap_boulder_app

_api_main.app = wrap_boulder_app(_api_main.app)
# uvicorn resolves "boulder.api.main:app" from the already-imported module.

Classes#

AuthMiddleware

Enforce session authentication on all non-public paths.

Functions#

login(request)

Redirect the browser to the Microsoft Entra ID authorization URL.

callback(request)

Exchange the authorization code for tokens and create a session.

logout(request)

Clear the session and token, then redirect to home.

me(request)

Return {"authenticated": bool} for the current session.

wrap_boulder_app(boulder_app)

Wrap boulder_app with Microsoft Entra ID authentication.

Module Contents#

class bloc.core.auth_server.AuthMiddleware(app, dispatch=None)#

Bases: starlette.middleware.base.BaseHTTPMiddleware

Enforce session authentication on all non-public paths.

  • Public paths (_PUBLIC_PATHS) pass through without a session check.

  • OPTIONS requests pass through to allow CORS preflight.

  • SKIP_AUTH=true bypasses auth (CI / local dev without credentials).

  • Unauthenticated API calls (/api/…) receive a 401 JSON response.

  • All other unauthenticated requests are redirected to /auth/login.

  • Access tokens nearing expiry (< 5 min remaining) are silently refreshed.

async dispatch(request, call_next)#
app#
dispatch_func#
async bloc.core.auth_server.login(request)#

Redirect the browser to the Microsoft Entra ID authorization URL.

async bloc.core.auth_server.callback(request)#

Exchange the authorization code for tokens and create a session.

async bloc.core.auth_server.logout(request)#

Clear the session and token, then redirect to home.

async bloc.core.auth_server.me(request)#

Return {"authenticated": bool} for the current session.

bloc.core.auth_server.wrap_boulder_app(boulder_app)#

Wrap boulder_app with Microsoft Entra ID authentication.

Auth routes are registered in the outer Starlette app so they are matched before Boulder’s SPA catch-all /{full_path:path} route. The Boulder app is mounted at / as the final fallback.

Parameters:

boulder_app – Boulder’s FastAPI ASGI application (boulder.api.main.app).

Returns:

Outer ASGI application with authentication. Pass this to uvicorn instead of the plain Boulder app.

Return type:

Starlette