TykTechnologies / tyk

Tyk Open Source API Gateway written in Go, supporting REST, GraphQL, TCP and gRPC protocols
Other
9.55k stars 1.07k forks source link

[TT-1028] ID Extractor Plugin Not Working With Multiple Auth #3220

Open nerdydread opened 4 years ago

nerdydread commented 4 years ago

Branch/Environment/Version

Describe the bug When using multiple authentication methods, the ID Extractor plugin does not work.

Reproduction steps Steps to reproduce the behavior:

  1. Import the attached API Definition (posted below).
  2. Clone the gRPC Java Custom Auth plugin project
  3. Overwrite the TykDispatcher.java file in the cloned project with the TykDispatcher.java file posted below
  4. Run the gRPC Java Custom Auth plugin
  5. Generate a token to access the API
  6. Curl the API rapidly in succession using your token. [example call: curl http://localhost:8080/custom-auth-api/get -b "apigw="]

Actual behavior Custom Auth plugin is called each time a request is made.

Expected behavior I expected that once the custom auth plugin had been called the first time and extended the expiration date for the token, the subsequent requests to the API with this token would not call the plugin as long as the token isn’t expired.

Additional context API Definition { "id": "5f0f78c03576690001be2975", "name": "Custom Auth API", "slug": "custom-auth-api", "listen_port": 0, "protocol": "", "enable_proxy_protocol": false, "api_id": "f412f29d7a1744215b56d4af4a24166a", "org_id": "5e9d9544a1dcd60001d0ed20", "use_keyless": false, "use_oauth2": false, "use_openid": false, "openid_options": { "providers": [], "segregate_by_client": false }, "oauth_meta": { "allowed_access_types": [], "allowed_authorize_types": [], "auth_login_redirect": "" }, "auth": { "use_param": false, "param_name": "", "use_cookie": false, "cookie_name": "", "auth_header_name": "Authorization", "use_certificate": false, "validate_signature": false, "signature": { "algorithm": "", "header": "", "secret": "", "allowed_clock_skew": 0, "error_code": 0, "error_message": "" } }, "auth_configs": { "authToken": { "use_param": false, "param_name": "", "use_cookie": true, "cookie_name": "apigw", "auth_header_name": "Authorization", "use_certificate": false, "validate_signature": false, "signature": { "algorithm": "", "header": "", "secret": "", "allowed_clock_skew": 0, "error_code": 0, "error_message": "" } }, "basic": { "use_param": false, "param_name": "", "use_cookie": false, "cookie_name": "", "auth_header_name": "Authorization", "use_certificate": false, "validate_signature": false, "signature": { "algorithm": "", "header": "", "secret": "", "allowed_clock_skew": 0, "error_code": 0, "error_message": "" } }, "coprocess": { "use_param": false, "param_name": "", "use_cookie": true, "cookie_name": "apigw", "auth_header_name": "Authorization", "use_certificate": false, "validate_signature": false, "signature": { "algorithm": "", "header": "", "secret": "", "allowed_clock_skew": 0, "error_code": 0, "error_message": "" } }, "hmac": { "use_param": false, "param_name": "", "use_cookie": false, "cookie_name": "", "auth_header_name": "Authorization", "use_certificate": false, "validate_signature": false, "signature": { "algorithm": "", "header": "", "secret": "", "allowed_clock_skew": 0, "error_code": 0, "error_message": "" } }, "jwt": { "use_param": false, "param_name": "", "use_cookie": false, "cookie_name": "", "auth_header_name": "Authorization", "use_certificate": false, "validate_signature": false, "signature": { "algorithm": "", "header": "", "secret": "", "allowed_clock_skew": 0, "error_code": 0, "error_message": "" } }, "oauth": { "use_param": false, "param_name": "", "use_cookie": false, "cookie_name": "", "auth_header_name": "Authorization", "use_certificate": false, "validate_signature": false, "signature": { "algorithm": "", "header": "", "secret": "", "allowed_clock_skew": 0, "error_code": 0, "error_message": "" } }, "oidc": { "use_param": false, "param_name": "", "use_cookie": false, "cookie_name": "", "auth_header_name": "Authorization", "use_certificate": false, "validate_signature": false, "signature": { "algorithm": "", "header": "", "secret": "", "allowed_clock_skew": 0, "error_code": 0, "error_message": "" } } }, "use_basic_auth": false, "basic_auth": { "disable_caching": false, "cache_ttl": 0, "extract_from_body": false, "body_user_regexp": "", "body_password_regexp": "" }, "use_mutual_tls_auth": false, "client_certificates": [], "upstream_certificates": {}, "pinned_public_keys": {}, "enable_jwt": false, "use_standard_auth": true, "use_go_plugin_auth": false, "enable_coprocess_auth": true, "jwt_signing_method": "", "jwt_source": "", "jwt_identity_base_field": "", "jwt_client_base_field": "", "jwt_policy_field_name": "", "jwt_default_policies": [], "jwt_issued_at_validation_skew": 0, "jwt_expires_at_validation_skew": 0, "jwt_not_before_validation_skew": 0, "jwt_skip_kid": false, "jwt_scope_to_policy_mapping": {}, "jwt_scope_claim_name": "", "notifications": { "shared_secret": "", "oauth_on_keychange_url": "" }, "enable_signature_checking": false, "hmac_allowed_clock_skew": -1, "hmac_allowed_algorithms": [], "request_signing": { "is_enabled": false, "secret": "", "key_id": "", "algorithm": "", "header_list": [], "certificate_id": "", "signature_header": "" }, "base_identity_provided_by": "auth_token", "definition": { "location": "header", "key": "x-api-version", "strip_path": false }, "version_data": { "not_versioned": true, "default_version": "", "versions": { "Default": { "name": "Default", "expires": "", "paths": { "ignored": [], "white_list": [], "black_list": [] }, "use_extended_paths": true, "extended_paths": {}, "global_headers": {}, "global_headers_remove": [], "global_size_limit": 0, "override_target": "" } } }, "uptime_tests": { "check_list": [], "config": { "expire_utime_after": 0, "service_discovery": { "use_discovery_service": false, "query_endpoint": "", "use_nested_query": false, "parent_data_path": "", "data_path": "", "port_data_path": "", "target_path": "", "use_target_list": false, "cache_timeout": 60, "endpoint_returns_list": false }, "recheck_wait": 0 } }, "proxy": { "preserve_host_header": false, "listen_path": "/custom-auth-api/", "target_url": "http://httpbin.org/", "disable_strip_slash": false, "strip_listen_path": true, "enable_load_balancing": false, "target_list": [], "check_host_against_uptime_tests": false, "service_discovery": { "use_discovery_service": false, "query_endpoint": "", "use_nested_query": false, "parent_data_path": "", "data_path": "", "port_data_path": "", "target_path": "", "use_target_list": false, "cache_timeout": 0, "endpoint_returns_list": false }, "transport": { "ssl_insecure_skip_verify": false, "ssl_ciphers": [], "ssl_min_version": 0, "ssl_force_common_name_check": false, "proxy_url": "" } }, "disable_rate_limit": false, "disable_quota": false, "custom_middleware": { "pre": [], "post": [], "post_key_auth": [], "auth_check": { "name": "TestAuthCheck", "path": "", "require_session": true, "raw_body_only": false }, "response": [], "driver": "grpc", "id_extractor": { "extract_from": "header", "extract_with": "regex", "extractor_config": { "header_name": "Cookie", "regex_expression": "apigw=(\\w+)", "regex_match_index": 0 } } }, "custom_middleware_bundle": "", "cache_options": { "cache_timeout": 60, "enable_cache": true, "cache_all_safe_requests": false, "cache_response_codes": [], "enable_upstream_cache_control": false, "cache_control_ttl_header": "" }, "session_lifetime": 0, "active": true, "internal": false, "auth_provider": { "name": "", "storage_engine": "", "meta": {} }, "session_provider": { "name": "", "storage_engine": "", "meta": {} }, "event_handlers": { "events": {} }, "enable_batch_request_support": false, "enable_ip_whitelisting": false, "allowed_ips": [], "enable_ip_blacklisting": false, "blacklisted_ips": [], "dont_set_quota_on_create": false, "expire_analytics_after": 0, "response_processors": [], "CORS": { "enable": false, "allowed_origins": [], "allowed_methods": [], "allowed_headers": [], "exposed_headers": [], "allow_credentials": false, "max_age": 24, "options_passthrough": false, "debug": false }, "domain": "", "certificates": [], "do_not_track": false, "tags": [], "enable_context_vars": false, "config_data": {}, "tag_headers": [], "global_rate_limit": { "rate": 0, "per": 0 }, "strip_auth_data": false, "enable_detailed_recording": false }

TykDispatcher.java

package com.tyktechnologies.tykmiddleware;

import coprocess.DispatcherGrpc;
import coprocess.CoprocessObject;
import coprocess.CoprocessSessionState;
import coprocess.CoprocessReturnOverrides;
import java.time.Instant;

public class TykDispatcher extends DispatcherGrpc.DispatcherImplBase {

    final String FOOBAR = "foobar";

    @Override
    public void dispatch(CoprocessObject.Object request,
            io.grpc.stub.StreamObserver<CoprocessObject.Object> responseObserver) {

        System.out.println("*** Incoming Request ***");
        System.out.println("Hook name: " + request.getHookName());

        final CoprocessObject.Object modifiedRequest = MyAuthHook(request);
        responseObserver.onNext(modifiedRequest);

        System.out.println("*** Transformed Request ***");

        responseObserver.onCompleted();
    }

    CoprocessObject.Object MyAuthHook(CoprocessObject.Object request) {
         String authHeader = request.getRequest().getHeadersOrDefault("Cookie", "");
         System.out.println("AuthHeader: " + authHeader);

        CoprocessObject.Object.Builder builder = request.toBuilder();
        builder.getSessionBuilder().setLastUpdated(String.valueOf(Instant.now().getEpochSecond()));
        //builder.getSessionBuilder().setIdExtractorDeadline(Instant.now().getEpochSecond() + 15);
        //authHeader = authHeader.replace("apigw=","");
        //System.out.println("New Auth Header: " + authHeader);
        builder.getSessionBuilder().setIdExtractorDeadline((System.currentTimeMillis() / 1000) + 5);
        builder.getSessionBuilder().putMetadata("token", "apigw=" + authHeader); 
        builder.getSessionBuilder().setRate(5.0);
        builder.getSessionBuilder().setPer(10.0);

        return builder.build();
    }
}
matiasinsaurralde commented 4 years ago

Hi, could you set the gateway log level in debug mode, trigger a request and share the full log? You can achieve this by setting the TYK_LOGLEVEL environment variable to debug or by setting the log_level property to debug in tyk.conf. It would be useful to inspect your plugin output as well (I see that there are some logging instructions in place).

christtyk commented 4 years ago

@matiasinsaurralde it relates to this.

@nerdydread FYI on Matias' request

nerdydread commented 4 years ago

plugin_output.txt gw.log @matiasinsaurralde Logs attached, please let me know if anything else is needed.