{"action":"created","issue":{"url":"https://api.github.com/repos/Mashape/kong/issues/546","labels_url":"https://api.github.com/repos/Mashape/kong/issues/546/labels{/name}","comments_url":"https://api.github.com/repos/Mashape/kong/issues/546/comments","events_url":"https://api.github.com/repos/Mashape/kong/issues/546/events","html_url":"https://github.com/Mashape/kong/pull/546","id":106830191,"number":546,"title":"[feature/plugin] JWT ","user":{"login":"thibaultCha","id":1125431,"avatar_url":"https://avatars.githubusercontent.com/u/1125431?v=3","gravatar_id":"","url":"https://api.github.com/users/thibaultCha","html_url":"https://github.com/thibaultCha","followers_url":"https://api.github.com/users/thibaultCha/followers","following_url":"https://api.github.com/users/thibaultCha/following{/other_user}","gists_url":"https://api.github.com/users/thibaultCha/gists{/gist_id}","starred_url":"https://api.github.com/users/thibaultCha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thibaultCha/subscriptions","organizations_url":"https://api.github.com/users/thibaultCha/orgs","repos_url":"https://api.github.com/users/thibaultCha/repos","events_url":"https://api.github.com/users/thibaultCha/events{/privacy}","received_events_url":"https://api.github.com/users/thibaultCha/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/Mashape/kong/labels/NEEDS%20REVIEW","name":"NEEDS REVIEW","color":"eb6420"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2015-09-16T18:15:41Z","updated_at":"2015-09-17T14:36:22Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/Mashape/kong/pulls/546","html_url":"https://github.com/Mashape/kong/pull/546","diff_url":"https://github.com/Mashape/kong/pull/546.diff","patch_url":"https://github.com/Mashape/kong/pull/546.patch"},"body":"This implements JWT validation as discussed in #519. It takes some elements from #401 but with use cases described in #519 only. It supports HMAC SHA-256 signed JWTs only.\r\n\r\nHere is what is implemented:\r\n\r\n```shell\r\n$ http :8001/apis/{api}/plugins name=jwt\r\nHTTP/1.1 200 OK\r\n...\r\n\r\n$ http POST :8001/consumers/{consumer}/jwt\r\nHTTP/1.1 201 Created\r\n\r\n{\r\n    \"consumer_id\": \"7bce93e1-0a90-489c-c887-d385545f8f4b\",\r\n    \"created_at\": 1442426001000,\r\n    \"id\": \"bcbfb45d-e391-42bf-c2ed-94e32946753a\",\r\n    \"key\": \"a36c3049b36249a3c9f8891cb127243c\",\r\n    \"secret\": \"e71829c351aa4242c2719cbfbe671c09\"\r\n}\r\n```\r\n\r\nCrafting of the JWT is done as follows:\r\n\r\nHeader:\r\n\r\n```json\r\n{\r\n  \"typ\": \"JWT\",\r\n  \"alg\": \"HS256\"\r\n}\r\n```\r\n\r\nClaims:\r\n\r\n```json\r\n{\r\n  \"iss\": \"a36c3049b36249a3c9f8891cb127243c\", // key from the consumer's jwt secret\r\n  \"iat\": 1442426454,\r\n  \"exp\": 1442430054,\r\n  \"nbf\": 1442426454\r\n}\r\n```\r\n\r\nSecret is `e71829c351aa4242c2719cbfbe671c09` as generated by Kong.\r\n\r\nFinal request with JWT is:\r\n\r\n```shell\r\n$ http :8000/{api path} 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMzZjMzA0OWIzNjI0OWEzYzlmODg5MWNiMTI3MjQzYyIsImV4cCI6MTQ0MjQzMDA1NCwibmJmIjoxNDQyNDI2NDU0LCJpYXQiOjE0NDI0MjY0NTR9.AhumfY35GFLuEEjrOXiaADo7Ae6gt_8VLwX7qffhQN4'\r\n```\r\n\r\nOr in querystring:\r\n\r\n```shell\r\n$ http ':8000/{api path}?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMzZjMzA0OWIzNjI0OWEzYzlmODg5MWNiMTI3MjQzYyIsImV4cCI6MTQ0MjQzMDA1NCwibmJmIjoxNDQyNDI2NDU0LCJpYXQiOjE0NDI0MjY0NTR9.AhumfY35GFLuEEjrOXiaADo7Ae6gt_8VLwX7qffhQN4'\r\n```\r\n\r\nIf the JWT is verified by Kong, then the request is proxied **untouched** to the upstream service.\r\n\r\n##### Customizations\r\n\r\n- The querystring parameter is customizable. \r\n- The users's `key` (which goes in the `iss` claim) is auto-generated if not specified but can be a `POST` parameter if a system needs to migrate to Kong.\r\n\r\n##### Improvements\r\n\r\nNow, @jasonmotylinski-dowjones, @lucamaraschi, @jerizm, @sinzone, @thefosk as you all took part in this, I would like to have feedback. Does this satisfies your use cases or does it lack a feature? Here is a list of features that this PR does **not** support but could implement:\r\n\r\n- Send the **decoded** claims of the JWT to the upstream service (as a JSON payload maybe?).\r\n- Validating other fields of the JWT (`exp`, `nbf`) and reject it if invalid. It currently only validates the signature.\r\n- Implement support for `jti`. Unique JWTs that cannot be replayed.\r\n\r\nSince all those are application specific I wanted feedback on whether or not they were required since I think they have value but were not mentioned in #519..."},"comment":{"url":"https://api.github.com/repos/Mashape/kong/issues/comments/141105953","html_url":"https://github.com/Mashape/kong/pull/546#issuecomment-141105953","issue_url":"https://api.github.com/repos/Mashape/kong/issues/546","id":141105953,"user":{"login":"tecnobrat","id":145406,"avatar_url":"https://avatars.githubusercontent.com/u/145406?v=3","gravatar_id":"","url":"https://api.github.com/users/tecnobrat","html_url":"https://github.com/tecnobrat","followers_url":"https://api.github.com/users/tecnobrat/followers","following_url":"https://api.github.com/users/tecnobrat/following{/other_user}","gists_url":"https://api.github.com/users/tecnobrat/gists{/gist_id}","starred_url":"https://api.github.com/users/tecnobrat/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tecnobrat/subscriptions","organizations_url":"https://api.github.com/users/tecnobrat/orgs","repos_url":"https://api.github.com/users/tecnobrat/repos","events_url":"https://api.github.com/users/tecnobrat/events{/privacy}","received_events_url":"https://api.github.com/users/tecnobrat/received_events","type":"User","site_admin":false},"created_at":"2015-09-17T14:36:22Z","updated_at":"2015-09-17T14:36:22Z","body":"I would love to have it decode the claim (or an option of doing so).\r\n\r\nAnything with the claim data is custom logic, better solved with the upstream service (authorization vs authentication). If we can have the only piece of our application that needs to know about how to decode the claim be inside kong, it drastically reduces what each upstream service needs to know.  The upstream service can just deal with authorization instead of authentication.\r\n\r\nBasically kong would decrypt the claim.  If it validates properly, it passes along the decrypted claim."}}