Skip to content

Commit

Permalink
JWT: add 'verifyClaimsAt' for explicitly specifying time
Browse files Browse the repository at this point in the history
Getting the current time requires a syscall; in a high volume
environment the syscall would be executed (redundantly) many times
per second.  Provide the 'verifyClaimsAt' function which allows
explicitly supplying a UTCTime at which to validate the JWT.

Fixes: #53
  • Loading branch information
frasertweedale committed Aug 10, 2017
1 parent 2b9f6f5 commit b3ce7f0
Showing 1 changed file with 35 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/Crypto/JWT.hs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ module Crypto.JWT
-- * Validating a JWT and extracting claims
, defaultJWTValidationSettings
, verifyClaims
, verifyClaimsAt
, HasAllowedSkew(..)
, HasAudiencePredicate(..)
, HasIssuerPredicate(..)
Expand Down Expand Up @@ -113,6 +114,7 @@ import Control.Lens (
Lens', _Just, over, preview, review, view,
Prism', prism', Cons, cons, uncons, iso, Iso')
import Control.Monad.Except (MonadError(throwError))
import Control.Monad.Reader (ReaderT, ask, runReaderT)
import Data.Aeson
import qualified Data.HashMap.Strict as M
import qualified Data.Text as T
Expand Down Expand Up @@ -503,13 +505,22 @@ instance ToCompact a => ToCompact (JWT a) where
toCompact (JWT a) = toCompact a


newtype WrappedUTCTime = WrappedUTCTime { getUTCTime :: UTCTime }

instance Monad m => MonadTime (ReaderT WrappedUTCTime m) where
currentTime = getUTCTime <$> ask


-- | Cryptographically verify a JWS JWT, then validate the
-- Claims Set, returning it if valid.
--
-- This is the only way to get at the claims of a JWS JWT,
-- enforcing that the claims are cryptographically and
-- semantically valid before the application can use them.
--
-- See also 'verifyClaimsAt' which allows you to explicitly specify
-- the time.
--
verifyClaims
::
( MonadTime m, HasAllowedSkew a, HasAudiencePredicate a
Expand All @@ -530,6 +541,30 @@ verifyClaims conf k (JWT jws) =
>>= either (throwError . review _JWTClaimsSetDecodeError) pure . eitherDecode
>>= validateClaimsSet conf


-- | Cryptographically verify a JWS JWT, then validate the
-- Claims Set, returning it if valid.
--
-- This is the same as 'verifyClaims' except that the time is
-- explicitly provided. If you process many requests per second
-- this will allow you to avoid unnecessary repeat system calls.
--
verifyClaimsAt
::
( HasAllowedSkew a, HasAudiencePredicate a
, HasIssuerPredicate a
, HasCheckIssuedAt a
, HasValidationSettings a
, AsError e, AsJWTError e, MonadError e m
, JWKStore k
)
=> a
-> k
-> SignedJWT
-> UTCTime
-> m ClaimsSet
verifyClaimsAt a k jwt = runReaderT (verifyClaims a k jwt) . WrappedUTCTime

-- | Create a JWS JWT
--
signClaims
Expand Down

0 comments on commit b3ce7f0

Please sign in to comment.