Resolve an authenticated identity from HTTP headers. Authentication order: 1. `Authorization: Bearer eyJ...` — JWT (if JwksRegistry configured) 2. `Authorization: Bearer ndb_...` — API key 3. Trust mode (no header required) — if configured
(
headers: &HeaderMap,
state: &AppState,
peer_addr: &str,
)
| 48 | /// 2. `Authorization: Bearer ndb_...` — API key |
| 49 | /// 3. Trust mode (no header required) — if configured |
| 50 | pub fn resolve_identity( |
| 51 | headers: &HeaderMap, |
| 52 | state: &AppState, |
| 53 | peer_addr: &str, |
| 54 | ) -> Result<AuthenticatedIdentity, ApiError> { |
| 55 | if let Some(auth_header) = headers.get("authorization") { |
| 56 | let auth_str = auth_header |
| 57 | .to_str() |
| 58 | .map_err(|_| ApiError::Unauthorized("invalid authorization header encoding".into()))?; |
| 59 | |
| 60 | if let Some(token) = auth_str.strip_prefix("Bearer ") { |
| 61 | let token = token.trim(); |
| 62 | |
| 63 | // Try JWT first (token has 2 dots = JWT format). |
| 64 | if let Some(identity) = try_validate_jwt(state, token) { |
| 65 | return Ok(identity); |
| 66 | } |
| 67 | |
| 68 | // Try API key. |
| 69 | if let Some(identity) = |
| 70 | session_auth::verify_api_key_identity(&state.shared, token, peer_addr, "HTTP") |
| 71 | { |
| 72 | return Ok(identity); |
| 73 | } |
| 74 | |
| 75 | return Err(ApiError::Unauthorized("invalid bearer token".into())); |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | if state.auth_mode == AuthMode::Trust { |
| 80 | return Ok(session_auth::trust_identity(&state.shared, "anonymous")); |
| 81 | } |
| 82 | |
| 83 | Err(ApiError::Unauthorized( |
| 84 | "missing Authorization: Bearer <token> header".into(), |
| 85 | )) |
| 86 | } |
| 87 | |
| 88 | /// Resolve both authenticated identity and auth context from HTTP headers. |
| 89 | /// |
no test coverage detected