@Override
    public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
        if (!(authentication instanceof X509CertificateAuthentication)) {
            throw new IllegalArgumentException("Unsupported authentication type: " + authentication.getClass().getName()
                    + ". Only X509CertificateAuthentication is supported!");
        }

        final X509CertificateAuthentication auth = (X509CertificateAuthentication) authentication;
        final String username = this.usernameExtractor.apply(auth);
        if (username == null) {
            log.debug("Could not find username");
            throw new UsernameNotFoundException("No username provided");
        }

        final UserDetails user = this.userDetailsService.loadUserByUsername(username);
        if (user == null) {
            log.debug("Could not find user '{}'", username);
            throw new UsernameNotFoundException("Unknown username: " + username);
        }
        log.debug("Authenticated as '{}'", username);
        return new X509CertificateAuthentication(user, auth.getCredentials(), user.getAuthorities());
    }
Creates a new X509CertificateAuthenticationProvider, which uses the given {@link Function} to extract the
username and uses the given {@link UserDetailsService} to lookup the user.

@param usernameExtractor The username extractor to use. The function should return null, if the username is
       missing.
@param userDetailsService The user details service to use.
grpc-server-spring-boot-starter/src/main/java/net/devh/boot/grpc/server/security/authentication/X509CertificateAuthenticationProvider.java