Merge feat/http-bearer-auth-middleware: Shared Bearer auth middleware

Implements src/server/auth.rs: bearer_auth_middleware (from_fn_with_state over
Arc<dyn IdentityProvider>, stashes Option<Identity> in request extensions),
extract_bearer_identity (Bearer-only: no/malformed/Basic/unresolvable → None,
not an error), ResolvedIdentity axum extractor. Wired into HttpAdapter router
via route_layer around gateway/openapi/mcp routes, excluding /healthz. 11 tests.

# Conflicts:
#	crates/alknet-http/Cargo.toml
#	crates/alknet-http/src/server/adapter.rs
#	crates/alknet-http/src/server/mod.rs
This commit is contained in:
2026-07-01 18:51:29 +00:00
5 changed files with 322 additions and 5 deletions

View File

@@ -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,7 @@ 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;
use crate::server::decoy::decoy_fallback;
use crate::server::healthz::healthz;
@@ -132,15 +134,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(healthz))
.route("/openapi.json", get(not_implemented))
.route("/mcp", post(not_implemented))
.route_layer(from_fn_with_state(auth_state.clone(), bearer_auth_middleware))
.route("/healthz", get(healthz))
.fallback(decoy_fallback);
let with_extras = match extra_routes {