swift-microservices/swift-authentication-vapor
Binding who is calling on Vapor: a bearer token, proved and logged in to the request.
The middleware
BearerAuthenticationMiddleware reads the Authorization header, proves the token with an Authenticator<String, Identity> from swift-authentication, and sets the identity in two places:
- the request's
auth, whichGuardMiddleware,req.auth.require, and route handlers read; - the request's
serviceContext, as aPrincipal<Identity, String>under
PrincipalKey<Identity, String>.
app.middleware.use(BearerAuthenticationMiddleware(authenticator: JWTAuthenticator<AppToken>(keys: keys)))
app.grouped(AppToken.guardMiddleware()).get("account") { req in
try req.auth.require(AppToken.self)
}The identity is any Authenticatable, so Vapor's own guard and require helpers work on it unchanged. A request with no token continues anonymously, which is what an open route needs: signing in mints the first token and has no caller yet. A token the authenticator declines continues unbound. A token it refuses is 401 Unauthorized, because absent and invalid are not the same thing. Requiring a caller is a route's decision, made with guardMiddleware().
The request's context, not the task's
Vapor 4 bridges its responder chain through event-loop futures, so a task-local bound in middleware does not reach a route. The request's serviceContext is the one that does, which is also how Vapor's own tracing middleware carries its span. Work that reads ServiceContext.current, such as an outgoing gRPC call presenting the token onward through swift-authentication-grpc, is run under it:
try await ServiceContext.withValue(req.serviceContext) {
try await upstream.call(request)
}Requirements
Swift 6.3, macOS 15 or Linux. Vapor 4.122.
Development
swift test
swift-format lint --strict --recursive Sources Tests # what the soundness check runsContributing
Pull requests are welcome. Keep a change focused, prove new behaviour with a test, and label the pull request with its semantic version impact.
License
MIT. See LICENSE.
Package Metadata
Repository: swift-microservices/swift-authentication-vapor
Default branch: main
README: README.md