Replace the boolean authenticator result with a typed AuthenticationResult
containing AuthenticationState (NotApplicable, Failed, Succeeded, Error)
to distinguish between non-applicability, rejected credentials, and
dependency failures.
All existing authentication behavior remains observably unchanged.
The old approach of the authentication middlewares had the problem that when an authenticator could not authenticate a request it would still send it to the next handler, in case that the next one can authenticate it. But if no authenticator could successfully authenticate the request, it would still be handled, which leads to unauthorized access.