swift-microservices/swift-authentication-hummingbird
Binding who is calling on Hummingbird: a bearer token, proved and set on the request context.
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 context's
identity, which HummingbirdAuth'sIsAuthenticatedMiddlewareand
route handlers read;
- the task's
ServiceContext, as aPrincipal<Identity, String>under
PrincipalKey<Identity, String>, which everything downstream reads, including outgoing gRPC calls that present the same token onward through swift-authentication-grpc.
let router = Router(context: BasicAuthRequestContext<AppToken>.self)
router.add(middleware: BearerAuthenticationMiddleware(authenticator: JWTAuthenticator<AppToken>(keys: keys)))
router.group("/account")
.add(middleware: IsAuthenticatedMiddleware())
.get("/") { _, context in context.identity! }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 IsAuthenticatedMiddleware.
Requirements
Swift 6.3, macOS 15 or Linux. Hummingbird 2.26, HummingbirdAuth 2.3.
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-hummingbird
Default branch: main
README: README.md