Authentication
Authentication is implemented by application-defined subclasses of Authenticator. An authenticator receives AxiSpark's ExecutionContext, reads credentials from the relevant transport context, validates them, and returns an identity value. This package does not select a token format or prescribe where identities come from.
Implement an authenticator
import { Injectable } from '@axisparkjs/di';
import { ExecutionContext } from '@axisparkjs/engine';
import { HttpContext } from '@axisparkjs/http';
import { Authenticator } from '@axisparkjs/security';
export interface Principal {
id: string;
role: 'reader' | 'admin';
}
@Injectable()
export class BearerAuthenticator extends Authenticator {
async authenticate(context: ExecutionContext): Promise<Principal | undefined> {
const request = (context as HttpContext).request;
const authorization = request.getHeader('authorization');
if (typeof authorization !== 'string' || !authorization.startsWith('Bearer ')) return undefined;
const token = authorization.slice('Bearer '.length);
return this.identityService.verify(token);
}
}
Use the context type for the transport your authenticator supports. A single authenticator can support multiple transports by narrowing or branching on the execution context, while separate classes often make transport-specific parsing easier to reason about. Constructor dependencies are supplied through AxiSpark dependency injection.
Return value and chain behavior
Return a truthy identity value (for example, a principal or claims object) to authenticate. Return undefined when credentials are missing, malformed, expired, or otherwise not accepted by this authenticator. All falsy results—including null, false, 0, and ''—mean authentication failure.
The engine tries configured authenticators in order and stops at the first truthy result. That result is stored as context.data; the engine also sets context.authenticated and context.authenticationMethod. If every authenticator returns a falsy result, the execution remains unauthenticated. Exceptions from an authenticator propagate through the normal AxiSpark error pipeline.
This ordered chain supports multiple credential mechanisms. For example, a bearer authenticator can be followed by an API-key authenticator. The first successful mechanism determines context.data; later authenticators do not overwrite it.
Optional authentication
Authentication middleware runs on configured transports even when a handler is not secured, so it can attach identity data for optional-authentication routes. The security guards enforce authentication only when @Secured() metadata marks the target. A public handler therefore remains public if the request has no valid credentials, while its handler can still inspect context.authenticated or context.data when credentials were provided and accepted.
If the target is secured and no authenticator succeeds, the authentication guard throws AuthenticationError before authorization enforcement.
Transport filtering
There are two levels of filtering:
import { ExecutionTransport } from '@axisparkjs/engine';
export class HttpBearerAuthenticator extends Authenticator {
static readonly transports = [ExecutionTransport.Http];
// ...
}
authenticator.transportsin plugin options enables or disables the authentication middleware for the whole transport.static transportson an authenticator decides which transports that particular implementation can handle.
Both default to all transports. An authenticator is skipped unless its list contains the current transport or ExecutionTransport.All.
Keep the middleware-level list enabled for every transport that has protected handlers. The authentication engine sets the securedMethod flag used by both guards. Disabling the middleware for a transport also skips this metadata check, so the guards will not enforce @Secured() on that transport.