mikyll opened a new issue, #11262:
URL: https://github.com/apache/apisix/issues/11262

   ### Current Behavior
   
   Note: I'm using Apisix Ingress Controller on Minikube, with Apisix CRDs.
   
   ### Case 1 (OK)
   - **ApisixConsumer** doesn't specify the `exp` configuration parameter;
   - the **JWT token** includes a `exp` claim, but it's expired;
   
   Result: the JWT validation fails due to `exp` claim, since the token is 
expired.
   
   ### Case 2 (?)
   - **ApisixConsumer** doesn't specify the `exp` configuration parameter;
   - the **JWT token** does not include a `exp` claim;
   
   Result: the JWT validation fails due to missing `exp`or `nbf` claims.
   
   ### Case 3 (OK)
   - **ApisixConsumer** specifies the `exp` configuration parameter;
   - the **JWT token** does not include a `exp` claim;
   
   Result: the JWT validation fails due to missing `exp`or `nbf` claims.
   
   
   ### Expected Behavior
   
   Do **not check** the `exp` and `nbf` claims _by default_, since the standard 
specification says they should be _optional_.
   
   Instead, verify these claims only if they are specifyied in ApisixConsumer 
fields, or maybe provide configuration parameters to enable/disable the check 
([Kong does something 
similar](https://docs.konghq.com/hub/kong-inc/jwt/configuration/#config-claims_to_verify)).
   
   ### References
   -  [RFC7519 # 
4.1.4](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4):
   > **4.1.4. "exp" (Expiration Time) Claim**
   \
      The "exp" (expiration time) claim identifies the expiration time on
      or after which the JWT MUST NOT be accepted for processing.  The
      processing of the "exp" claim requires that the current date/time
      MUST be before the expiration date/time listed in the "exp" claim.
   \
      Implementers MAY provide for some small leeway, usually no more than
      a few minutes, to account for clock skew.  Its value MUST be a number
      containing a NumericDate value. **Use of this claim is OPTIONAL.**
    
    -  [RFC7519 # 
4.1.5](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5):
   > **4.1.5. "nbf" (Not Before) Claim**
   \
      The "nbf" (not before) claim identifies the time before which the JWT
      MUST NOT be accepted for processing.  The processing of the "nbf"
      claim requires that the current date/time MUST be after or equal to
      the not-before date/time listed in the "nbf" claim.  Implementers MAY
      provide for some small leeway, usually no more than a few minutes, to
      account for clock skew.  Its value MUST be a number containing a
      NumericDate value. **Use of this claim is OPTIONAL.**
   
   ### Error Logs
   
   _No response_
   
   ### Steps to Reproduce
   
   **NB**: I'm setting Service `apisix-gateway` as a _LoadBalancer_ for 
simplicity. I'm also using some mock RS256 public/private keys.
   
   1. Start a minikube cluster and launch tunnel command, leaving the terminal 
running in background:
   ```bash
   minikube start --driver=docker
   minikube tunnel
   ```
   2. Install Apisix Ingress Controller:
   ```bash
   # Update charts
   helm repo add apisix https://charts.apiseven.com
   helm repo add bitnami https://charts.bitnami.com/bitnami
   helm repo update
   
   # Create namespace
   kubectl create ns ingress-apisix
   
   # Install Apisix
   helm install apisix apisix/apisix \
     --set service.type=LoadBalancer \
     --namespace ingress-apisix \
     --set ingress-controller.enabled=true \
     --set ingress-controller.config.apisix.serviceNamespace=ingress-apisix
   ```
   Once the installation is completed, minikube tunnel should pick up the 
`apisix-gateway` service and we will be able to send a curl request to the 
proxy on localhost:
   ```bash
   curl -s -i "localhost:80/"
   HTTP/1.1 404 Not Found
   Date: Wed, 15 May 2024 14:07:06 GMT
   Content-Type: text/plain; charset=utf-8
   Transfer-Encoding: chunked
   Connection: keep-alive
   Server: APISIX/3.9.1
   
   {"error_msg":"404 Route Not Found"}
   ```
   3. Declare Kubernetes resources used for testing:
   
   <details close>
   <summary>Show/Hide</summary>
   
   ```yaml
   # File 'resources.yaml'
   
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: httpbin
   spec:
     replicas: 1
     selector:
       matchLabels:
         run: httpbin
     template:
       metadata:
         labels:
           run: httpbin
       spec:
         containers:
         - name: httpbin
           image: kennethreitz/httpbin
           ports:
           - containerPort: 80
             protocol: TCP
   ---
   apiVersion: v1
   kind: Service
   metadata:
     name: httpbin
   spec:
     ports:
     - port: 80
       protocol: TCP
       targetPort: 80
     selector:
       run: httpbin
   ---
   apiVersion: apisix.apache.org/v2
   kind: ApisixConsumer
   metadata:
     name: httpbin-test-auth-jwt
   spec:
     authParameter:
       jwtAuth:
         value:
           key: "my-key"
           algorithm: "RS256"
           base64_secret: false
           public_key: |
             -----BEGIN PUBLIC KEY-----
             MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCozMxH2Mo
             4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0/IzW7yWR7QkrmBL7jTKEn5u
             +qKhbwKfBstIs+bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyeh
             kd3qqGElvW/VDL5AaWTg0nLVkjRo9z+40RQzuVaE8AkAFmxZzow3x+VJYKdjykkJ
             0iT9wCS0DRTXu269V264Vf/3jvredZiKRkgwlL9xNAwxXFg0x/XFw005UWVRIkdg
             cKWTjpBP2dPwVZ4WWC+9aGVd+Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbc
             mwIDAQAB
             -----END PUBLIC KEY-----
   ---
   apiVersion: apisix.apache.org/v2
   kind: ApisixRoute
   metadata:
     name: httpbin-test-auth-jwt
   spec:
     http:
     - name: rule1
       match:
         paths:
         - /*
       backends:
       - serviceName: httpbin
         servicePort: 80
       authentication:
         enable: true
         type: jwtAuth
   ```
   
   </details>
   
   4. Create them inside the cluster:
   ```bash
   kubectl apply -f resources.yaml
   ```
   5.  Test the route
   ```bash
   curl -s -i -X GET "localhost/get?foo1=bar1&foo2=bar2"
   HTTP/1.1 401 Unauthorized
   Date: Thu, 16 May 2024 10:05:55 GMT
   Content-Type: text/plain; charset=utf-8
   Transfer-Encoding: chunked
   Connection: keep-alive
   Server: APISIX/3.9.1
   
   {"message":"Missing JWT token in request"}
   ```
   6. Use the following token:
       - header:
       ```json
       {
         "alg": "RS256",
         "typ": "JWT"
       }
       ```
       - payload **without expiration claim**:
       ```json
       {
         "key": "my-key",
         "sub": "1234567890",
         "name": "John Doe",
         "iat": 1516239022
       }
       ```
   7. Save the token in a variable:
   ```bash
   
JWT_TOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJteS1rZXkiLCJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.kQ-h3S0wgwDWIaOV_JNOlpck8JXAxAAtIto3hzHee4PHisx8xZcajSaX6PXf5cQW-H8uIOf7UUJCr3_62LV2hy4sSLwXcpzK5QIYRu4GO6g4q9Lv3yhYw0h2rP0bcFmkoVM91S7T0BEFA9m3H8zyKpF6qy9GscC7xoNL49W7TVhoetm4GeiKpngLCvUbGEjLWUrzx1o9JRruOe6ydv4VhOi8angH4By7kcs-XKLepVr1HyzQacw8Lyoyu4CumviefpWkwzDfDINf0r3Ad-WqAsoOGBhJh4fybe6xpIO_uWOJ95JWHUaQE3HWM_Q9fUuZvyR1p7oizbmWUxipaYIaZA"
   ```
   8. Open `apisix` gateway logs in another terminal, to detect the "expiration 
check" message:
   ```bash
   kubectl logs -n "ingress-apisix" -f deployments/$(kubectl get deployment -n 
"ingress-apisix" --no-headers | cut -f1 -d' '| grep 'apisix$')
   ```
   9. Send a HTTP request with the token:
   ```bash
   curl -s -i -X GET "localhost/get?foo1=bar1&foo2=bar2" -H "Authorization: 
Bearer ${JWT_TOKEN}"                                                            
     HTTP/1.1 401 Unauthorized
   Date: Thu, 16 May 2024 10:14:35 GMT
   Content-Type: text/plain; charset=utf-8
   Transfer-Encoding: chunked
   Connection: keep-alive
   Server: APISIX/3.9.1
   
   {"message":"failed to verify jwt"}
   ```
   10. We can see the warning message in apisix logs:
   ```
   2024/05/16 10:19:20 [warn] 72#72: *1053197 [lua] jwt-auth.lua:381: 
phase_func(): failed to verify jwt: Missing one of claims - [ nbf, exp ]., 
client: 10.244.0.1, server: _, request: "GET /get?foo1=bar1&foo2=bar2 
HTTP/1.1", host: "localhost"
   2024/05/16 10:19:20 [warn] 72#72: *1053197 [lua] plugin.lua:1160: 
run_plugin(): jwt-auth exits with http status code 401, client: 10.244.0.1, 
server: _, request: "GET /get?foo1=bar1&foo2=bar2 HTTP/1.1", host: "localhost"
   10.244.0.1 - - [16/May/2024:10:19:20 +0000] localhost "GET 
/get?foo1=bar1&foo2=bar2 HTTP/1.1" 401 46 0.000 "-" "curl/8.2.1" - - - 
"http://localhost";
   ```
   
   ### Environment
   
   - APISIX version (run `apisix version`):
   ```
   /usr/local/openresty//luajit/bin/luajit ./apisix/cli/apisix.lua version
   3.9.1
   ```
   - Operating system (run `uname -a`): 
   ```
   Linux apisix-69f8d49c7b-vdcvf 5.15.133.1-microsoft-standard-WSL2 #1 SMP Thu 
Oct
   5 21:02:42 UTC 2023 x86_64 GNU/Linux
   ```
   - OpenResty / Nginx version (run `openresty -V` or `nginx -V`):
   
   <details close>
   <summary>Show/Hide</summary>
   
   ```
   nginx version: openresty/1.25.3.1
   built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
   built with OpenSSL 3.2.0 23 Nov 2023
   TLS SNI support enabled
   configure arguments: --prefix=/usr/local/openresty/nginx --with-cc-opt='-O2 
-DAPISIX_RUNTIME_VER=1.2.0 -DNGX_GRPC_CLI_ENGI
   NE_PATH=/usr/local/openresty/libgrpc_engine.so 
-DNGX_HTTP_GRPC_CLI_ENGINE_PATH=/usr/local/openresty/libgrpc_engine.so -DNG
   X_LUA_ABORT_AT_PANIC -I/usr/local/openresty/zlib/include 
-I/usr/local/openresty/pcre/include -I/usr/local/openresty/openss
   l3/include' --add-module=../ngx_devel_kit-0.3.3 
--add-module=../echo-nginx-module-0.63 --add-module=../xss-nginx-module-0.
   06 --add-module=../ngx_coolkit-0.2 
--add-module=../set-misc-nginx-module-0.33 
--add-module=../form-input-nginx-module-0.12
    --add-module=../encrypted-session-nginx-module-0.09 
--add-module=../srcache-nginx-module-0.33 --add-module=../ngx_lua-0.1
   0.26 --add-module=../ngx_lua_upstream-0.07 
--add-module=../headers-more-nginx-module-0.37 --add-module=../array-var-nginx-
   module-0.06 --add-module=../memc-nginx-module-0.20 
--add-module=../redis2-nginx-module-0.15 --add-module=../redis-nginx-mo
   dule-0.3.9 --add-module=../ngx_stream_lua-0.0.14 
--with-ld-opt='-Wl,-rpath,/usr/local/openresty/luajit/lib -Wl,-rpath,/usr
   /local/openresty/wasmtime-c-api/lib -L/usr/local/openresty/zlib/lib 
-L/usr/local/openresty/pcre/lib -L/usr/local/openresty
   /openssl3/lib 
-Wl,-rpath,/usr/local/openresty/zlib/lib:/usr/local/openresty/pcre/lib:/usr/local/openresty/openssl3/lib'
 --
   add-module=/tmp/tmp.EQbG5FbABp/openresty-1.25.3.1/../mod_dubbo-1.0.2 
--add-module=/tmp/tmp.EQbG5FbABp/openresty-1.25.3.1/.
   ./ngx_multi_upstream_module-1.2.0 
--add-module=/tmp/tmp.EQbG5FbABp/openresty-1.25.3.1/../apisix-nginx-module-1.16.0
 --add-
   
module=/tmp/tmp.EQbG5FbABp/openresty-1.25.3.1/../apisix-nginx-module-1.16.0/src/stream
 --add-module=/tmp/tmp.EQbG5FbABp/op
   enresty-1.25.3.1/../apisix-nginx-module-1.16.0/src/meta 
--add-module=/tmp/tmp.EQbG5FbABp/openresty-1.25.3.1/../wasm-nginx-
   module-0.7.0 
--add-module=/tmp/tmp.EQbG5FbABp/openresty-1.25.3.1/../lua-var-nginx-module-v0.5.3
 --add-module=/tmp/tmp.EQbG
   5FbABp/openresty-1.25.3.1/../grpc-client-nginx-module-v0.5.0 
--add-module=/tmp/tmp.EQbG5FbABp/openresty-1.25.3.1/../lua-re
   sty-events-0.2.0 --with-poll_module --with-pcre-jit --with-stream 
--with-stream_ssl_module --with-stream_ssl_preread_modul
   e --with-http_v2_module --with-http_v3_module --without-mail_pop3_module 
--without-mail_imap_module --without-mail_smtp_mo
   dule --with-http_stub_status_module --with-http_realip_module 
--with-http_addition_module --with-http_auth_request_module
   --with-http_secure_link_module --with-http_random_index_module 
--with-http_gzip_static_module --with-http_sub_module --wit
   h-http_dav_module --with-http_flv_module --with-http_mp4_module 
--with-http_gunzip_module --with-threads --with-compat --w
   ith-stream --without-pcre2 --with-http_ssl_module
   ```
   
   </details>
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to