class ServiceAuthenticationFilter extends ZuulFilter {

    @Override
    public Object run() {
        final RequestContext context = RequestContext.getCurrentContext();

        boolean rejected = false;
        AuthenticationCommand cmd = null;

        final String serviceId = (String) context.get(SERVICE_ID_KEY);
        try {
            String jwtToken = authenticationService.getJwtTokenFromRequest(context.getRequest()).orElse(null);
            cmd = serviceAuthenticationService.getAuthenticationCommand(serviceId, jwtToken);

            // Verify JWT validity if it is required for the schema
            if (
                (jwtToken != null) && cmd.isRequiredValidJwt() &&
                !authenticationService.validateJwtToken(jwtToken).isAuthenticated()
            ) {
                    rejected = true;
            }
        } catch (TokenExpireException tee) {
            cmd = null;
        } catch (AuthenticationException ae) {
            rejected = true;
        } catch (Exception e) {
            throw new ZuulRuntimeException(
                new ZuulException(e, HttpStatus.INTERNAL_SERVER_ERROR.value(), String.valueOf(e))
            );
        }

        if (rejected) {
            context.setSendZuulResponse(false);
            context.setResponseStatusCode(SC_UNAUTHORIZED);
        } else if (cmd != null) {
            try {
                // Update ZUUL context by authentication schema
                cmd.apply(null);
            } catch (Exception e) {
                throw new ZuulRuntimeException(
                    new ZuulException(e, HttpStatus.INTERNAL_SERVER_ERROR.value(), String.valueOf(e))
                );
            }
        }

        return null;
    }

}