Skip to main content

Authorization

The movement endpoints are gated on the Camera.Operate role, and requests arrive already carrying a bearer token. That token has to be minted somewhere — and this API is where the login flow lives.

The one idea to hold on to​

The API runs the OAuth2/OIDC flow against Azure AD B2C CIAM in two endpoints, delegating the cryptography to the shared JWTService. It's a standard authorization-code exchange:

// GET /Authorization/login → build the authorize URL the browser is sent to
var result = _jwtService.GetFrontendAuthorizeRequest();

// GET /Authorization/callback?code=&state= → swap the code for tokens
return Ok(await _jwtService.GetFrontendTokensAsync(code, state));

login returns the CIAM authorize URL; the user signs in there; CIAM redirects back to callback with a code; the API exchanges it for access and id tokens. Those tokens — and the roles inside them, like Camera.Operate — are what the rest of the API authorizes against.

Gotcha: this API mints tokens; the proxy injects them

There are two halves to "authenticated request," and they live in different places. This API's Authorization endpoints mint the tokens during login. The frontend's server-side proxy is what attaches the bearer to every subsequent API call. If requests are arriving without a bearer (and getting 401s), the problem is usually the proxy's injection, not this login flow — check that the route is in the proxy's matcher before suspecting CIAM.

Wrapping up​

Authorization is a thin CIAM authorization-code flow: login builds the authorize URL, callback exchanges the code for tokens via the Infrastructure JWTService (certificate client assertion, frontend flavor), and the roles in those tokens gate everything else. Minting happens here; injecting the bearer onto later requests happens in the frontend proxy.

Next, the other direction — how the API pushes updates out and takes callbacks in: Real-Time & Engine Callbacks.