From 60cfa068c111059c14dd176655336e9fc20c8c45 Mon Sep 17 00:00:00 2001 From: Guillaume Buisson Date: Fri, 31 Jan 2020 13:25:37 +0100 Subject: [PATCH] set kid when signing with a key, allow setting the value --- src/clj_jwt/core.clj | 16 ++++-- test/clj_jwt/core_test.clj | 113 +++++++++++++++++++------------------ 2 files changed, 69 insertions(+), 60 deletions(-) diff --git a/src/clj_jwt/core.clj b/src/clj_jwt/core.clj index f759c1a..789f7c0 100644 --- a/src/clj_jwt/core.clj +++ b/src/clj_jwt/core.clj @@ -8,6 +8,8 @@ [clojure.string :as str])) (def ^:private DEFAULT_SIGNATURE_ALGORITHM :HS256) +(def ^:private DEFAULT_KID nil) + (def ^:private map->encoded-json (comp url-safe-encode-str #(json/write-str % :key-fn write-key))) (def ^:private encoded-json->map (comp #(json/read-str % :key-fn read-key) @@ -48,18 +50,22 @@ (defprotocol JsonWebSignature "Protocol for JonWebSignature" (set-alg [this alg] "Set algorithm name to JWS Header Parameter") - (sign [this key] [this alg key] "Set signature to this token") + (set-kid [this kid] "Set Key ID to JWS Header Parameter") + (sign [this key] [this alg key] [this alg key kid] "Set signature to this token") (verify [this] [this key] [this algorithm key] "Verify this token")) (extend-protocol JsonWebSignature JWT (set-alg [this alg] (assoc-in this [:header :alg] (name alg))) - + (set-kid [this kid] + (assoc-in this [:header :kid] kid)) (sign - ([this key] (sign this DEFAULT_SIGNATURE_ALGORITHM key)) - ([this alg key] - (let [this* (set-alg this alg) + ([this key] (sign this DEFAULT_SIGNATURE_ALGORITHM key DEFAULT_KID)) + ([this alg key] (sign this alg key DEFAULT_KID)) + ([this alg key kid] + (let [this* (cond-> (set-alg this alg) + (some? kid) (set-kid kid)) sign-fn (get-signature-fn alg) data (str (encoded-header this*) "." (encoded-claims this*))] (assoc this* :signature (sign-fn key data) :encoded-data data)))) diff --git a/test/clj_jwt/core_test.clj b/test/clj_jwt/core_test.clj index 84c322b..6200b27 100644 --- a/test/clj_jwt/core_test.clj +++ b/test/clj_jwt/core_test.clj @@ -28,73 +28,76 @@ (def ec-dmy-key (with-bc-provider-fn #(public-key "test/files/ec/dummy.key"))) (facts "JWT tokenize" - (fact "Plain JWT should be generated." - (-> claim jwt to-str) - => "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpc3MiOiJmb28ifQ.") + (fact "Plain JWT should be generated." + (-> claim jwt to-str) + => "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpc3MiOiJmb28ifQ.") - (fact "If unknown algorithm is specified, exception is throwed." - (-> claim jwt (sign :DUMMY "foo")) => (throws Exception)) + (fact "If unknown algorithm is specified, exception is throwed." + (-> claim jwt (sign :DUMMY "foo")) => (throws Exception)) - (fact "HS256 signed JWT should be generated." - (-> claim jwt (sign "foo") to-str) - => (str "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.8yUIo-xkh537lD_CZycqS1zB" - "NhBNkIrcfzaFgwt8zdg") + (fact "HS256 signed JWT should be generated." + (-> claim jwt (sign "foo") to-str) + => (str "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.8yUIo-xkh537lD_CZycqS1zB" + "NhBNkIrcfzaFgwt8zdg") - (-> claim jwt (sign :HS256 "foo") to-str) - => (str "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.8yUIo-xkh537lD_CZycqS1zB" - "NhBNkIrcfzaFgwt8zdg")) + (-> claim jwt (sign :HS256 "foo") to-str) + => (str "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.8yUIo-xkh537lD_CZycqS1zB" + "NhBNkIrcfzaFgwt8zdg")) - (fact "HS384 signed JWT should be generated." - (-> claim jwt (sign :HS384 "foo") to-str) - => (str "eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.34ZaTLCZGBAfcCryhYaFYy8Z" - "-47do1cftq365YmvIcubonhGdRnvpgV8s_iG_lvd")) + (fact "HS384 signed JWT should be generated." + (-> claim jwt (sign :HS384 "foo") to-str) + => (str "eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.34ZaTLCZGBAfcCryhYaFYy8Z" + "-47do1cftq365YmvIcubonhGdRnvpgV8s_iG_lvd")) - (fact "HS512 signed JWT should be generated." - (-> claim jwt (sign :HS512 "foo") to-str) - => (str "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.58Q4HxaxKAZIffEyDI2eRM_2" - "L7mK7NlNwOq8v96gbfZLMM7r2hxXKuwvMLez2XivUUCEyoaVB1Yz3vGtwAvSZQ")) + (fact "HS512 signed JWT should be generated." + (-> claim jwt (sign :HS512 "foo") to-str) + => (str "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.58Q4HxaxKAZIffEyDI2eRM_2" + "L7mK7NlNwOq8v96gbfZLMM7r2hxXKuwvMLez2XivUUCEyoaVB1Yz3vGtwAvSZQ")) - (fact "RS256 signed JWT should be generated." - (-> claim jwt (sign :RS256 rsa-prv-key) to-str) - => (str "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.ZIjAlGryslu1APkgY1eCmaK7" - "GDINiGX-htlD1-33F4VXK8lUXbdm1n9F1fpHcOFksScniWMvC5f9520jdxyb5c-9CmXz21iDtFdFKWGG" - "zlT_hPjZ0Ta_M8goReBO0L-nDM5hJHxzEqgSZQ7tkcJ18PCdxeMia5NMRV0shGMMUzU") + (fact "RS256 signed JWT should be generated." + (-> claim jwt (sign :RS256 rsa-prv-key) to-str) + => (str "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.ZIjAlGryslu1APkgY1eCmaK7" + "GDINiGX-htlD1-33F4VXK8lUXbdm1n9F1fpHcOFksScniWMvC5f9520jdxyb5c-9CmXz21iDtFdFKWGG" + "zlT_hPjZ0Ta_M8goReBO0L-nDM5hJHxzEqgSZQ7tkcJ18PCdxeMia5NMRV0shGMMUzU") - (-> claim jwt (sign :RS256 rsa-enc-prv-key) to-str) - => (str "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.E20DLUOR5VeoTKtH5FjR71rm" - "_rZV2AdXYDQCxqHpMWyZSO6wO4g67phTD727izDxd_NjuNXd2m7Atth7tGABaMhqHLh9EUwba_0nTbw6" - "mc_4mWaK4KBq8LG4WErQnFAVhzGbo1aEK_J7iasuUCfnxN9fZeBBUGH_h5JgPogCPdA")) + (-> claim jwt (sign :RS256 rsa-prv-key "foo") to-str) + => "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImZvbyJ9.eyJpc3MiOiJmb28ifQ.hYL0352XhNo0z5u6queNjnVBeKxFXwyB1ELLk1G009eTQN5srC2dDdG9k66Free0vNpreCTGq1im4cQUvBUi12Fsyls1p7VBVnIABuc6ZUjyyLD7fDtXF_MqGksPrCcffQlW4Qj2WA_CkRU9qJCwvU-H5c1HIn6QX29hdeu1kzY" - (fact "RS384 signed JWT should be generated." - (-> claim jwt (sign :RS384 rsa-prv-key) to-str) - => (str "eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.sWyMCwJhztfOcSoxRRiCAioB" - "H5F8WFJs5t8DxPV0D7JvB9JwaN8reIQ7kFKJiQWFbhrC7tnlT5UDX9z3fyLjdmNvLTSOII3J9UPpidE1" - "4WvqnXk5DV8k4QxTdWHRufssDFZe7Bsq5yBRAGZos2e8U9hOuqxCib7EjGCe09PdDhg") + (-> claim jwt (sign :RS256 rsa-enc-prv-key) to-str) + => (str "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.E20DLUOR5VeoTKtH5FjR71rm" + "_rZV2AdXYDQCxqHpMWyZSO6wO4g67phTD727izDxd_NjuNXd2m7Atth7tGABaMhqHLh9EUwba_0nTbw6" + "mc_4mWaK4KBq8LG4WErQnFAVhzGbo1aEK_J7iasuUCfnxN9fZeBBUGH_h5JgPogCPdA")) - (-> claim jwt (sign :RS384 rsa-enc-prv-key) to-str) - => (str "eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.Uz3ZGXNuuKYsmoslBrNJnVKC" - "GW-dptW-eOWPrTGVN1P54bgjS6QbhwE-PPL2HHGUIYlebVmHb2RKLLvmQ8y63NZ1QSXEk8QBz5-bwy6Y" - "m_QCYh4tfvZYheH97zHcLF3GDLlfrodukO9gGc1xpiXJiZMtIso6sGACHmXNn4LA1bk")) + (fact "RS384 signed JWT should be generated." + (-> claim jwt (sign :RS384 rsa-prv-key) to-str) + => (str "eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.sWyMCwJhztfOcSoxRRiCAioB" + "H5F8WFJs5t8DxPV0D7JvB9JwaN8reIQ7kFKJiQWFbhrC7tnlT5UDX9z3fyLjdmNvLTSOII3J9UPpidE1" + "4WvqnXk5DV8k4QxTdWHRufssDFZe7Bsq5yBRAGZos2e8U9hOuqxCib7EjGCe09PdDhg") - (fact "RS512 signed JWT should be generated." - (-> claim jwt (sign :RS512 rsa-prv-key) to-str) - => (str "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.QKK5oOrVU5e0eG0nt7a_3Hzw" - "v1YJIp1F3iSKVgbdjWyp6rhyS4O4HEql6UxUOVDvf_aTrO4NG81dIo_wzjI1LBNCVtwKhR-8KUFs4Yg3" - "1NLwBMazIzxX_IfkpIkUPuyDGrca7pksJ9dppte33mMK3MDv0RQQqgXiJpbLRGWSNrs") + (-> claim jwt (sign :RS384 rsa-enc-prv-key) to-str) + => (str "eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.Uz3ZGXNuuKYsmoslBrNJnVKC" + "GW-dptW-eOWPrTGVN1P54bgjS6QbhwE-PPL2HHGUIYlebVmHb2RKLLvmQ8y63NZ1QSXEk8QBz5-bwy6Y" + "m_QCYh4tfvZYheH97zHcLF3GDLlfrodukO9gGc1xpiXJiZMtIso6sGACHmXNn4LA1bk")) - (-> claim jwt (sign :RS512 rsa-enc-prv-key) to-str) - => (str "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.P6ER78xL8AlV4BXrtTtBIcsc" - "JOktKH03Uj12mqjiS6o1h4Cf7QHKXjWxe33hrEgkzcYBHDqw7wH915f6ZnB5mkvDtBkLinA9gK0M2rfB" - "7NqAbxXYMDXti2PhV9PgRzOp97zPCSD98bML0Cy89E8sPcnM7-07wWOK4yhuoTWyV_8")) + (fact "RS512 signed JWT should be generated." + (-> claim jwt (sign :RS512 rsa-prv-key) to-str) + => (str "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.QKK5oOrVU5e0eG0nt7a_3Hzw" + "v1YJIp1F3iSKVgbdjWyp6rhyS4O4HEql6UxUOVDvf_aTrO4NG81dIo_wzjI1LBNCVtwKhR-8KUFs4Yg3" + "1NLwBMazIzxX_IfkpIkUPuyDGrca7pksJ9dppte33mMK3MDv0RQQqgXiJpbLRGWSNrs") - (fact "'exp', 'nbf', 'iat' claims should be converted as IntDate." - (let [d (date-time 2000 1 2 3 4 5) - claim (merge claim {:exp (plus d (days 1)) :nbf d :iat d :dmy d}) - token (jwt claim)] - (-> token :claims :exp) => 946868645 - (-> token :claims :nbf) => 946782245 - (-> token :claims :iat) => 946782245 - (-> token :claims :dmy) => d))) + (-> claim jwt (sign :RS512 rsa-enc-prv-key) to-str) + => (str "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb28ifQ.P6ER78xL8AlV4BXrtTtBIcsc" + "JOktKH03Uj12mqjiS6o1h4Cf7QHKXjWxe33hrEgkzcYBHDqw7wH915f6ZnB5mkvDtBkLinA9gK0M2rfB" + "7NqAbxXYMDXti2PhV9PgRzOp97zPCSD98bML0Cy89E8sPcnM7-07wWOK4yhuoTWyV_8")) + + (fact "'exp', 'nbf', 'iat' claims should be converted as IntDate." + (let [d (date-time 2000 1 2 3 4 5) + claim (merge claim {:exp (plus d (days 1)) :nbf d :iat d :dmy d}) + token (jwt claim)] + (-> token :claims :exp) => 946868645 + (-> token :claims :nbf) => 946782245 + (-> token :claims :iat) => 946782245 + (-> token :claims :dmy) => d))) (facts "JWT verify" (fact "Unknown signature algorithm should be thrown exception."