JWT issue (No suitable claim)

I’m hitting an API with JWT authentication through Tyk, but it’s unable to read the claims.

I’ve left it as the default, so it should be looking for sub to use as a user ID, however I’m getting

no suitable claims for user ID were found

{
“data”: {
“id”: 41251
},
“sub”: 41251,
“iss”: {REDACTED},
“iat”: 1547140017,
“exp”: 1547226417,
“nbf”: 1547140017,
“jti”: “tOfIgXVfdvGqwt9z”
}

This is what the token looks like when decoded. So there should be no trouble taking the value from sub if I’m correct?

Hi

Can you share an api definition you are using these tokens with and i’ll test an example jwt against it

Josh

{
  "api_model": {},
  "api_definition": {
    "api_id": "0e50b3af70764581717ccc85255d40f5",
    "upstream_certificates": {},
    "use_keyless": false,
    "enable_coprocess_auth": false,
    "jwt_disable_issued_at_validation": false,
    "custom_middleware": {
      "pre": [],
      "post": [],
      "post_key_auth": [],
      "auth_check": {
        "name": "",
        "path": "",
        "require_session": false
      },
      "response": [],
      "driver": "",
      "id_extractor": {
        "extract_from": "",
        "extract_with": "",
        "extractor_config": {}
      }
    },
    "disable_quota": false,
    "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": ""
    },
    "enable_ip_blacklisting": false,
    "tag_headers": [],
    "pinned_public_keys": {},
    "expire_analytics_after": 0,
    "domain": "",
    "openid_options": {
      "providers": [],
      "segregate_by_client": false
    },
    "jwt_policy_field_name": "",
    "active": true,
    "config_data": {},
    "notifications": {
      "shared_secret": "",
      "oauth_on_keychange_url": ""
    },
    "auth": {
      "auth_header_name": "Authorization",
      "use_certificate": false
    },
    "check_host_against_uptime_tests": false,
    "auth_provider": {
      "name": "",
      "storage_engine": "",
      "meta": {}
    },
    "blacklisted_ips": [],
    "hmac_allowed_clock_skew": -1,
    "dont_set_quota_on_create": false,
    "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": "",
          "cache_timeout": 60
        },
        "recheck_wait": 0
      }
    },
    "enable_jwt": true,
    "do_not_track": false,
    "name": "Node JWT",
    "jwt_disable_expires_at_validation": false,
    "slug": "node-jwt",
    "oauth_meta": {
      "allowed_access_types": [],
      "allowed_authorize_types": [],
      "auth_login_redirect": ""
    },
    "CORS": {
      "enable": false,
      "max_age": 24,
      "allow_credentials": false,
      "exposed_headers": [],
      "allowed_headers": [],
      "options_passthrough": false,
      "debug": false,
      "allowed_origins": [],
      "allowed_methods": []
    },
    "event_handlers": {
      "events": {}
    },
    "proxy": {
      "target_url": "REDACTED",
      "endpoint_returns_list": false,
      "cache_timeout": 0,
      "parent_data_path": "",
      "service_discovery": {
        "endpoint_returns_list": false,
        "cache_timeout": 0,
        "parent_data_path": "",
        "query_endpoint": "",
        "use_discovery_service": false,
        "target_path": "",
        "use_target_list": false,
        "use_nested_query": false,
        "data_path": "",
        "port_data_path": ""
      },
      "check_host_against_uptime_tests": false,
      "transport": {
        "ssl_ciphers": [],
        "ssl_min_version": 0,
        "proxy_url": ""
      },
      "target_list": [],
      "query_endpoint": "",
      "use_discovery_service": false,
      "_sd_show_port_path": false,
      "preserve_host_header": false,
      "use_target_list": false,
      "strip_listen_path": true,
      "use_nested_query": false,
      "data_path": "",
      "port_data_path": "",
      "enable_load_balancing": false,
      "listen_path": "/0e50b3af70764581717ccc85255d40f5/"
    },
    "client_certificates": [],
    "use_basic_auth": 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": {
            "ignored": [],
            "white_list": [],
            "black_list": [],
            "transform": [],
            "transform_response": [],
            "transform_jq": [],
            "transform_jq_response": [],
            "transform_headers": [],
            "transform_response_headers": [],
            "hard_timeouts": [],
            "circuit_breakers": [],
            "url_rewrites": [],
            "virtual": [],
            "size_limits": [],
            "method_transforms": [],
            "track_endpoints": [],
            "do_not_track_endpoints": [],
            "validate_json": []
          },
          "global_headers": {},
          "global_headers_remove": [],
          "global_size_limit": 0,
          "override_target": ""
        }
      }
    },
    "use_standard_auth": false,
    "session_lifetime": 0,
    "disable_rate_limit": false,
    "definition": {
      "location": "header",
      "key": "x-api-version",
      "strip_path": false
    },
    "use_oauth2": false,
    "jwt_source": "REDACTED",
    "jwt_signing_method": "hmac",
    "jwt_identity_base_field": "sub",
    "allowed_ips": [],
    "org_id": "5ab3cc97a8d11a00017332a7",
    "enable_ip_whitelisting": false,
    "global_rate_limit": {
      "rate": 0,
      "per": 0
    },
    "enable_context_vars": false,
    "tags": [],
    "basic_auth": {
      "disable_caching": false,
      "cache_ttl": 0
    },
    "session_provider": {
      "name": "",
      "storage_engine": "",
      "meta": {}
    },
    "strip_auth_data": false,
    "id": "5c1132cf82d7bf0001117198",
    "enable_signature_checking": false,
    "use_openid": false,
    "jwt_skip_kid": false,
    "enable_batch_request_support": false,
    "jwt_disable_not_before_validation": false,
    "response_processors": [],
    "use_mutual_tls_auth": false
  },
  "hook_references": [],
  "is_site": false,
  "sort_by": 0
}

I’ve redacted the target URL and jwt source/secret for obvious reasons.

Cheers.

Hi did you manage to work this out?

I’m having the exact same problem as yours.

cheers

Hi, yes I did in the end (no thanks to this useless forum :grinning:)

I cannot remember off the top of my head, however I think it was confusion with the sub.
I don’t think it looks for the actual subject of a JWT, but rather a field inside the JWT payload.

So basically, in your Tyk API config, under Authentication. Set the Identity Source as sub, then make sure you have a sub property in the payload. Also make sure you have the policy setup and in there too.

For example, on jwt.io your payload should decode to:

{
  "policy": "XXXXXX", // policy hash you want to use
  "sub": XXXX, // this is the sub - usually User ID or whatever
  "iat": 1588869515,
  "exp": 1589474315
}

Hope this helps. It took me a while.