Software /
code /
prosody
Comparison
util/jwt.lua @ 12705:008a7097fdc5
util.jwt: Provide built-in token expiry support (defaults to 3600s lifetime)
To avoid every user of the library needing to add and verify expiry info, this
is now handled by util.jwt itself (if not overridden or disabled).
Issuing tokens that are valid forever is bad practice and rarely desired, and
the default token lifetime is now 3600s (1 hour).
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Mon, 11 Jul 2022 13:28:29 +0100 (2022-07-11) |
parent | 12704:31a2bd84191d |
child | 12706:108b1758bd8d |
comparison
equal
deleted
inserted
replaced
12704:31a2bd84191d | 12705:008a7097fdc5 |
---|---|
150 ES256 = new_ecdsa_algorithm("ES256", crypto.ecdsa_sha256_sign, crypto.ecdsa_sha256_verify); | 150 ES256 = new_ecdsa_algorithm("ES256", crypto.ecdsa_sha256_sign, crypto.ecdsa_sha256_verify); |
151 RS256 = new_rsa_algorithm("RS256"), RS384 = new_rsa_algorithm("RS384"), RS512 = new_rsa_algorithm("RS512"); | 151 RS256 = new_rsa_algorithm("RS256"), RS384 = new_rsa_algorithm("RS384"), RS512 = new_rsa_algorithm("RS512"); |
152 PS256 = new_rsa_algorithm("PS256"), PS384 = new_rsa_algorithm("PS384"), PS512 = new_rsa_algorithm("PS512"); | 152 PS256 = new_rsa_algorithm("PS256"), PS384 = new_rsa_algorithm("PS384"), PS512 = new_rsa_algorithm("PS512"); |
153 }; | 153 }; |
154 | 154 |
155 local function new_signer(algorithm, key_input) | 155 local function new_signer(algorithm, key_input, options) |
156 local impl = assert(algorithms[algorithm], "Unknown JWT algorithm: "..algorithm); | 156 local impl = assert(algorithms[algorithm], "Unknown JWT algorithm: "..algorithm); |
157 local key = (impl.load_private_key or impl.load_key)(key_input); | 157 local key = (impl.load_private_key or impl.load_key)(key_input); |
158 local sign = impl.sign; | 158 local sign = impl.sign; |
159 local default_ttl = (options and options.default_ttl) or 3600; | |
159 return function (payload) | 160 return function (payload) |
161 local issued_at; | |
162 if not payload.iat then | |
163 issued_at = os.time(); | |
164 payload.iat = issued_at; | |
165 end | |
166 if not payload.exp then | |
167 payload.exp = (issued_at or os.time()) + default_ttl; | |
168 end | |
160 return sign(key, payload); | 169 return sign(key, payload); |
161 end | 170 end |
162 end | 171 end |
163 | 172 |
164 local function new_verifier(algorithm, key_input) | 173 local function new_verifier(algorithm, key_input, options) |
165 local impl = assert(algorithms[algorithm], "Unknown JWT algorithm: "..algorithm); | 174 local impl = assert(algorithms[algorithm], "Unknown JWT algorithm: "..algorithm); |
166 local key = (impl.load_public_key or impl.load_key)(key_input); | 175 local key = (impl.load_public_key or impl.load_key)(key_input); |
167 local verify = impl.verify; | 176 local verify = impl.verify; |
177 local check_expiry = not (options and options.accept_expired); | |
178 local claim_verifier = options and options.claim_verifier; | |
168 return function (token) | 179 return function (token) |
169 return verify(key, token); | 180 local ok, payload = verify(key, token); |
181 if ok then | |
182 local expires_at = check_expiry and payload.exp; | |
183 if expires_at then | |
184 if type(expires_at) ~= "number" then | |
185 return nil, "invalid-expiry"; | |
186 elseif expires_at < os.time() then | |
187 return nil, "token-expired"; | |
188 end | |
189 end | |
190 if claim_verifier and not claim_verifier(payload) then | |
191 return nil, "incorrect-claims"; | |
192 end | |
193 end | |
194 return ok, payload; | |
170 end | 195 end |
171 end | 196 end |
172 | 197 |
173 return { | 198 return { |
174 new_signer = new_signer; | 199 new_signer = new_signer; |