JWT 기본 정의

* JWT : 3가지로 구분됨
header.payload.signature

* Header
- Token타입 / 알고리즘을 저장함
- typ : Token type (JWT)
- alg : Algorithm (해시알고리즘)

* Payload
- 토큰에 담을 정보 기입 ( Claim 으로 표시함 )
- 등록된 클레임 (발급자/만료일 등등 사전 정의된 형식)
> NGINX Plus 는 해당 Claim 에 대해 Expire Token 여부 확인 가능
- 공개 클레임 ( URI 형식 )
> NGINX Plus 는 해당 Claim 에 대해 확인 및 Access 제어
- 비공개 클레임 ( 서버-클라이언트 사이에 협의하에 사용되는 형식 )
> 해당 Claim 사전 정의시, NGINX Plus 에서 활용 가능한 부분

* Signature
- 서명값
- 서버에서는 해당 시그니쳐(키) 값을 알고있어야, 들어오는 JWT Token 에 대해 인증 가능


NGINX Plus JWT Token Validation Scope


JWT 내 nbf (NotBeFore)/ exp(Expire) 에 대해 기본 Claim 확인


추가적인 Token 내 정보 확인(유효성 검사) 의 경우, map 활용 




NGINX Plus with JWT 기본 Flow

  • Client / JWT Issuer / Nginx Plus / API Servers 구조 





JWT 인증 Flow - Demo Lab

  • JWT Token Validation 을 NGINX Plus 가 처리

  • API Key Registry 의 경우 미구현, NGINX Config 내 Key 값을 포함함

  • JWT Token 관련 NGINX Plus Config

    • nginx.conf
  • 
    # Test API JWT Auth 
    ## Http Context 내 
    log_format jwt '$remote_addr - $remote_user [$time_local] "$request" '
                   '$status $body_bytes_sent "$http_referer" "$http_user_agent" '
                   '$jwt_header_alg $jwt_claim_sub';
    
    server {
        listen 30000;
        status_zone server_JWTAuth_NGINXApi_30000;
    
        location / {
                allow 0.0.0.0;
                access_log /var/log/nginx/access.log jwt;
                error_log /var/log/nginx/host.jwt.error.log debug;
    
                auth_jwt on; 
                auth_jwt_key_file jwt_key.jwk;
                proxy_pass http://10.250.11.11:8080$request_uri;  ## Test API server 
        }
    

    해당 k 값 base64 decode 하면 됨

    # Key 값 Encode ( Key name : json_key ) 
    echo -n json_key | base64 | tr '+/' '-_' | tr -d '='
    # kty (KeyType) : oct ( symmetric key )
    
    #[09:15:42 root@bm-nginx-api /etc/nginx]$ cat jwt_key.jwk
    {"keys":
        [{
            "k":"anNvbl9rZXk",
            "kty":"oct"
        }]
    }
    
    
    

JWT Token Create 

  • JWT Token Create with CLI
    • Token Create 시, Web Page Create 권장 / _ 등 특수문자 여부 확인 필요
  • * Header - "alg" : "HS256", "typ": "JWT"
    * PayLoad - "uid" : "10"
    * Signature : json_key 
    -------------------------------------------------------------------------
    * Header Create 
    jwt_header=$(echo -n '{"alg":"HS256","typ":"JWT"}' | base64)
    echo $jwt_header
    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
    
    * Payload Create
    payload=$(echo -n '{"uid":"10"}' | base64)
    echo $payload
    eyJ1aWQiOiIxMCJ9
    
    * Verify Signature Create
    jwt_signature=$(echo -n $jwt_header.$payload | openssl dgst -sha256 -hmac json_key -binary |  base64 | tr '+/' '-_' | tr -d '=')
    #echo -n $jwt_header.$payload | openssl dgst -sha256 -hmac json_key -binary | openssl base64 -e -A | sed s/\\+/-/ | sed -E s/=+$//
    
    * Merge - Create Token
    jwt_token=$(echo -n $jwt_header.$payload.$jwt_signature)
    echo $jwt_token
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxMCJ9.lZTgfbQLHksFJ5bbmPTMGmYupCBaXms_WgjRgYhTHSg
    
  • JWT Token Create With GUI

JWT Access 

  • JWT Access (CURL)

  • curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxMCJ9.lZTgfbQLHksFJ5bbmPTMGmYupCBaXms_WgjRgYhTHSg" http://10.250.11.16:30000/api/7/nginx
    
    # Access Log
    10.250.11.16 - - [20/Sep/2022:09:17:04 +0900] "GET /api/7/nginx HTTP/1.1" 200 193 "-" "curl/7.29.0" HS256 -
    
  • JWT Access ( Web)
    • Header 에 Authorization Add ( Bearer $JWT_TOKEN )

  • JWT Access ( Postman )
    • Authorization - Bearer Token 활용

JWT Access Fail Log

  • Key 등의 Not Match 등에 따른 Authorization Fail 여부 로그상 확인 가능

    # Debug Log
    2022/09/20 09:09:55 [info] 20426#20426: *702 JWT HS validation failed, client: 10.250.11.16, server: , request: "GET /api/7/nginx HTTP/1.1", host: "10.250.11.16:30000"
    

  JWT Token Validation

  • JWT
    • jwt.io 에 JWT Token 값 입력 ,Validation 가능 ( Header / Payload 확인 )
  • Siguature ( Server )
    • K 값의 경우, base64 Decode 활용