feat(http): implement shared Bearer auth middleware (resolve_from_token, stash Identity in request extensions)
Add src/server/auth.rs with bearer_auth_middleware axum layer that extracts the Authorization: Bearer header, resolves via IdentityProvider::resolve_from_token, and stashes Option<Identity> in request extensions. Shared by HTTP gateway routes and the to_mcp rmcp service (research §4.4). No token, malformed header, or failed resolution all yield None (unauthenticated, not an error) — Bearer-only auth mechanism (ADR-004). Includes ResolvedIdentity axum extractor reading from extensions, and wires the middleware into the HttpAdapter router around the gateway/openapi/mcp routes (excluding the raw /healthz route).
This commit is contained in:
@@ -15,6 +15,7 @@ use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use axum::http::StatusCode;
|
||||
use axum::middleware::from_fn_with_state;
|
||||
use axum::response::IntoResponse;
|
||||
use axum::routing::{any, get, post};
|
||||
use axum::Router;
|
||||
@@ -28,6 +29,8 @@ use alknet_call::registry::registration::OperationRegistry;
|
||||
use alknet_core::auth::{AuthContext, IdentityProvider};
|
||||
use alknet_core::types::{Connection, HandlerError, ProtocolHandler, StreamError};
|
||||
|
||||
use super::auth::bearer_auth_middleware;
|
||||
|
||||
const ALPN_HTTP1: &[u8] = b"http/1.1";
|
||||
const ALPN_H2: &[u8] = b"h2";
|
||||
|
||||
@@ -123,15 +126,17 @@ impl HttpAdapter {
|
||||
}
|
||||
|
||||
fn build_router(state: RouterState, extra_routes: Option<Router>) -> Router {
|
||||
let auth_state = Arc::clone(&state.identity_provider);
|
||||
let default: Router<RouterState> = Router::new()
|
||||
.route("/search", any(not_implemented))
|
||||
.route("/schema", any(not_implemented))
|
||||
.route("/call", any(not_implemented))
|
||||
.route("/batch", any(not_implemented))
|
||||
.route("/subscribe", any(not_implemented))
|
||||
.route("/healthz", get(not_implemented))
|
||||
.route("/openapi.json", get(not_implemented))
|
||||
.route("/mcp", post(not_implemented));
|
||||
.route("/mcp", post(not_implemented))
|
||||
.route_layer(from_fn_with_state(auth_state.clone(), bearer_auth_middleware))
|
||||
.route("/healthz", get(not_implemented));
|
||||
|
||||
let with_extras = match extra_routes {
|
||||
Some(extra) => {
|
||||
|
||||
Reference in New Issue
Block a user