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 )
- Header 에 Authorization Add ( Bearer $JWT_TOKEN )
- JWT Access ( Postman )
- Authorization - Bearer Token 활용
- 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 활용