Как исправить неопределенную ошибку короткой строки в Varnish VCL при настройке Fastly CDN - PullRequest
0 голосов
/ 20 ноября 2018

Я пытаюсь настроить аутентификацию на основе токенов в Fastly CDN с Varnish VCL и использую этот пример фрагмента VCL для генерации и проверки токенов JWT здесь -

sub vcl_recv {
    #FASTLY recv

    if (req.request != "HEAD" && req.request != "GET" && req.request != "FASTLYPURGE") {
        return(pass);
    }

    // Generate synth
    if(req.url ~ "generate") {
        error 901;
    }

    // Validate token
    if(req.url ~ "validate") {
        // Ensure token exists and parse into regex
        if (req.http.X-JWT !~ "^([a-zA-Z0-9\-_]+)?\.([a-zA-Z0-9\-_]+)?\.([a-zA-Z0-9\-_]+)?$") {
            // Forbidden
            error 403 "Forbidden";
        }

        // Extract token header, payload and signature
        set req.http.X-JWT-Header = re.group.1;
        set req.http.X-JWT-Payload = re.group.2;
        set req.http.X-JWT-Signature = digest.base64url_nopad_decode(re.group.3);
        set req.http.X-JWT-Valid-Signature = digest.hmac_sha256("SupSecretStr", 
        req.http.X-JWT-Header "." req.http.X-JWT-Payload);
        // Validate signature
        if(digest.secure_is_equal(req.http.X-JWT-Signature, req.http.X-JWT-Valid-Signature)) {
            // Decode payload
            set req.http.X-JWT-Payload = digest.base64url_nopad_decode(req.http.X-JWT-Payload);
            set req.http.X-JWT-Expires = regsub(req.http.X-JWT-Payload, {"^.*?"exp"\s*?:\s*?([0-9]+).*?$"}, "\1");

            // Validate expiration
            if (time.is_after(now, std.integer2time(std.atoi(req.http.X-JWT-Expires)))) {
               // Unauthorized
               synthetic {"{"sign":""} req.http.X-JWT-Signature {"","header":""} req.http.X-JWT-Header {"","payload":""} req.http.X-JWT-Payload {"","valid": ""} req.http.X-JWT-Valid-Signature {""}"};
               return(deliver);
            }

            // OK
            synthetic {"{"header2":""} req.http.X-JWT-Header {"","payload":""} req.http.X-JWT-Payload {"","sign":""} req.http.X-JWT-Signature {"","valid": ""} req.http.X-JWT-Valid-Signature {""}"};
           return(deliver);
        } else {
            // Forbidden
            synthetic {"{"header3":""} req.http.X-JWT-Header {"","payload":""} req.http.X-JWT-Payload {"","sign":""} req.http.X-JWT-Signature {"","valid": ""} req.http.X-JWT-Valid-Signature {""}"};
             return(deliver);
        }
    }

    return(lookup);
}

sub vcl_error {
    #FASTLY error

    // Generate JWT token
    if (obj.status == 901) {
        set obj.status = 200;
        set obj.response = "OK";
        set obj.http.Content-Type = "application/json";

        set obj.http.X-UUID = randomstr(8, "0123456789abcdef") "-" randomstr(4, "0123456789abcdef") "-4" randomstr(3, "0123456789abcdef") "-" randomstr(1, "89ab") randomstr(3, "0123456789abcdef") "-" randomstr(12, "0123456789abcdef");

        set obj.http.X-JWT-Issued = now.sec;
        set obj.http.X-JWT-Expires = strftime({"%s"}, time.add(now, 3600s));

        set obj.http.X-JWT-Header = digest.base64url_nopad({"{"alg":"HS256","typ":"JWT""}{"}"});
        set obj.http.X-JWT-Payload = digest.base64url_nopad({"{"sub":""} obj.http.X-UUID {"","exp":"} obj.http.X-JWT-Expires {","iat":"} obj.http.X-JWT-Issued {","iss":"Fastly""}{"}"});
        set obj.http.X-JWT-Signature = digest.base64url_nopad(digest.hmac_sha256("SupSecretStr", obj.http.X-JWT-Header "." obj.http.X-JWT-Payload));

        set obj.http.X-JWT = obj.http.X-JWT-Header "." obj.http.X-JWT-Payload "." obj.http.X-JWT-Signature;
        unset obj.http.X-UUID;
        unset obj.http.X-JWT-Issued;
        unset obj.http.X-JWT-Expires;
        unset obj.http.X-JWT-Header;
        unset obj.http.X-JWT-payload;
        unset obj.http.X-JWT-Signature;
        synthetic {"{"payload":""} obj.http.X-JWT-Payload {"","header":""} obj.http.X-JWT-Header {"","sign":""} obj.http.X-JWT-Signatre {"","token": ""} obj.http.X-JWT {""}"};
        return(deliver);
    }

    // Valid token
    if (obj.status == 902) {
        set obj.status = 200;
        set obj.response = "OK";
        set obj.http.Content-Type = "application/json";

        synthetic {"{ "token": ""} req.http.X-JWT {"" }"};
        return(deliver);
    }

}

Теперь, когда я пытаюсь скомпилировать этовозвращает -

Syntax error: Unterminated _short-string_
at: (input Line 106 Pos 197)
               synthetic {"{"sign":""} req.http.X-JWT-Signature {"","header":""} req.http.X-JWT-Header {"","payload":""} req.http.X-JWT-Payload {"","valid": ""} req.http.X-JWT-Valid-Signature {""}"};

Похоже, что я не так корректно экранирую значения здесь во время синтетического блока.

Единственная причина, по которой я пытаюсь добавить этот синтетический блок в подпрограмму vcl_recv, заключается в том, что я хочу проверить, как дайджест генерирует токен JWT и проверяет его, и с этим я хотел создать аналогичные токены JWT нана стороне сервера в Node.Js, поэтому я пытался вывести различные промежуточные части токена для отладки.

Я не совсем знаком с синтаксисом и семантикой Varnish, но все же я искал помощь в поиске любых документов, касающихся этой подпрограммы расписания, но пока не нашел ни одного.

Итак, кто-нибудь может помочь в том, как это исправить, и чтобы vcl_recv, vcl_error интерполировали различные промежуточные значения в ответе json.

Я пытался использовать некоторые из основанных на Node.J base64библиотеки декодирования url для декодирования возвращенных частей токена и возможность декодировать часть заголовка и полезной нагрузки, но часть подписи, которую я не могу сгенерировать из Node.Js.Итак, кто-нибудь может подсказать, что эквивалентно base64url_nopad () в node.js или любых библиотеках javascript?

Для части шифрования hmac_256 мы пытаемся использовать библиотеку шифрования и создаем hmac, подобный crypto.createHmac ('sha256', 'SupSecretStr'). Update (). Digest ('hex');но все библиотеки base64 кодируют URL в js, я думаю, что возвращают дополненные URL, поэтому часть этого дайджеста hmac 256, закодированная в base64, не совпадает с той, что была создана с помощью лака

1 Ответ

0 голосов
/ 22 ноября 2018

Мой инструмент синтаксической окраски говорит мне почти то же самое, что и сообщение об ошибке: вы облажались ваши кавычки: -)

Ваш последний блок {""}"}; открывает котировки ({"), сразузакрывая их ("}), вы открываете простые кавычки " и новая строка появляется перед тем, как их закрывать.

Чтобы исправить, просто поставьте пробел между окончательной кавычкой json: {"" }"};

...