class PreAuthenticatedAuthenticationProvider extends TimeMeasuringAuthenticationProvider<AuthenticationResult> {

    @Override
    protected AuthenticationResult tryToAuthenticate(final RequestContext requestContext,
            final DittoHeaders dittoHeaders) {

        final Optional<String> preAuthOpt = getPreAuthenticated(requestContext);

        if (preAuthOpt.isEmpty()) {
            return DefaultAuthenticationResult.failed(dittoHeaders, getAuthenticationFailedException(dittoHeaders));
        }

        final String preAuthenticatedSubject = preAuthOpt.get();

        final List<AuthorizationSubject> authorizationSubjects = getAuthorizationSubjects(preAuthenticatedSubject);
        if (authorizationSubjects.isEmpty()) {
            return toFailedAuthenticationResult(
                    buildFailedToExtractAuthorizationSubjectsException(preAuthenticatedSubject, dittoHeaders),
                    dittoHeaders);
        }

        final AuthorizationContext authContext =
                AuthorizationModelFactory.newAuthContext(DittoAuthorizationContextType.PRE_AUTHENTICATED_HTTP,
                        authorizationSubjects);

        LOGGER.withCorrelationId(dittoHeaders)
                .info("Pre-authentication has been applied resulting in AuthorizationContext <{}>.", authContext);

        return DefaultAuthenticationResult.successful(dittoHeaders, authContext);
    }

    private  PreAuthenticatedAuthenticationProvider();

}