A digitally signed or MACed JWT
Modulejose-0.11Haskell2010
Crypto.JWT
JSON Web Token implementation (RFC 7519). A JWT is a JWS with a payload of claims to be transferred between two parties.
JWTs use the JWS compact serialisation. See Crypto.JOSE.Compact for details.
- 8 types
- 7 classes
- 14 values
- Packagejose-0.11
- Exports29
- LanguageHaskell2010
- LicenceApache-2.0
- SourceJWT.hs
Overview / HOWTO
0 declarationsBasic usage
import Crypto.JWT
mkClaims :: IO ClaimsSet
mkClaims = do
t <- currentTime
pure $ emptyClaimsSet
& claimIss ?~ "alice"
& claimAud ?~ Audience ["bob"]
& claimIat ?~ NumericDate t
doJwtSign :: JWK -> ClaimsSet -> IO (Either JWTError SignedJWT)
doJwtSign jwk claims = runJOSE $ do
alg <- bestJWSAlg jwk
signClaims jwk (newJWSHeader ((), alg)) claims
doJwtVerify :: JWK -> SignedJWT -> IO (Either JWTError ClaimsSet)
doJwtVerify jwk jwt = runJOSE $ do
let config = defaultJWTValidationSettings (== "bob")
verifyClaims config jwk jwt
Some JWT libraries have a function that takes two strings: the "secret" (a symmetric key) and the raw JWT. The following function achieves the same:
verify :: L.ByteString -> L.ByteString -> IO (Either JWTError ClaimsSet)
verify k s = runJOSE $ do
let
k' = fromOctets k -- turn raw secret into symmetric JWK
audCheck = const True -- should be a proper audience check
jwt <- decodeCompact s -- decode JWT
verifyClaims (defaultJWTValidationSettings audCheck) k' jwt
Supporting additional claims via subtypes
For applications that use additional claims, define a data type that wraps
ClaimsSet and includes fields for the additional claims. You will also need
to define FromJSON if verifying JWTs, and ToJSON if producing JWTs. The
following example is taken from
RFC 7519 §3.1.
import qualified Data.Aeson.KeyMap as M
data Super = Super { jwtClaims :: ClaimsSet, isRoot :: Bool }
instance HasClaimsSet Super where
claimsSet f s = fmap (\a' -> s { jwtClaims = a' }) (f (jwtClaims s))
instance FromJSON Super where
parseJSON = withObject "Super" $ \o -> Super
<$> parseJSON (Object o)
<*> o .: "http://example.com/is_root"
instance ToJSON Super where
toJSON s =
ins "http://example.com/is_root" (isRoot s) (toJSON (jwtClaims s))
where
ins k v (Object o) = Object $ M.insert k (toJSON v) o
ins _ _ a = a
Use signJWT and verifyJWT when using custom payload types (instead of
signClaims and verifyClaims which are specialised to ClaimsSet).
API
0 declarationsCreating a JWT
Create a JWS JWT. The payload can be any type with a ToJSON instance. See also signClaims which uses ClaimsSet as the payload type.
Does not set any fields in the Claims Set, such as "iat"
("Issued At") Claim. The payload is encoded as-is.
Validating a JWT and extracting claims
Acquire the default validation settings.
RFC 7519 §4.1.3. states that applications MUST identify itself with a value in the audience claim, therefore a predicate must be supplied.
The other defaults are:
defaultValidationSettings for JWS verification
Zero clock skew tolerance when validating nbf, exp and iat claims
iat claim is checked
issuer claim is not checked
Cryptographically verify a JWS JWT, then validate the Claims Set, returning it if valid. The claims are validated at the current system time.
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.
This function is abstracted over any payload type with HasClaimsSet and FromJSON instances. The verifyClaims variant uses ClaimsSet as the payload type.
See also verifyClaimsAt which allows you to explicitly specify the time of validation (against which time-related claims will be validated).
Maximum allowed skew when validating the nbf, exp and iat claims.
Methods
Instances1HasAllowedSkew
HasJWTValidationSettings a => HasAllowedSkew aDefined in jose-0.11 · Crypto.JWT
Predicate for checking values in the aud claim.
Methods
audiencePredicate :: Lens' s (StringOrURI -> Bool)
Instances1HasAudiencePredicate
HasJWTValidationSettings a => HasAudiencePredicate aDefined in jose-0.11 · Crypto.JWT
Predicate for checking the iss claim.
Methods
issuerPredicate :: Lens' s (StringOrURI -> Bool)
Instances1HasIssuerPredicate
HasJWTValidationSettings a => HasIssuerPredicate aDefined in jose-0.11 · Crypto.JWT
Whether to check that the iat claim is not in the future.
Methods
checkIssuedAt :: Lens' s Bool
Instances1HasCheckIssuedAt
HasJWTValidationSettings a => HasCheckIssuedAt aDefined in jose-0.11 · Crypto.JWT
Instances1HasJWTValidationSettings
HasJWTValidationSettings JWTValidationSettingsDefined in jose-0.11 · Crypto.JWT
Methods
jWTValidationSettings :: Lens' c JWTValidationSettingsjwtValidationSettingsAllowedSkew :: Lens' c NominalDiffTimejwtValidationSettingsAudiencePredicate :: Lens' c (StringOrURI -> Bool)jwtValidationSettingsCheckIssuedAt :: Lens' c BooljwtValidationSettingsIssuerPredicate :: Lens' c (StringOrURI -> Bool)jwtValidationSettingsValidationSettings :: Lens' c ValidationSettings
Instances1HasJWTValidationSettings
HasJWTValidationSettings JWTValidationSettingsDefined in jose-0.11 · Crypto.JWT
Specifying the verification time
Constructors
Instances1MonadTime
Monad m => MonadTime (ReaderT WrappedUTCTime m)Defined in jose-0.11 · Crypto.JWTmonotonicTime = pure 0. jose doesn't use this so we fake it
Variant of verifyJWT where the validation time is provided by caller. If you process many tokens per second this lets you avoid unnecessary repeat system calls.
Claims Set
The JWT Claims Set represents a JSON object whose members are
the registered claims defined by RFC 7519. To construct a
ClaimsSet use emptyClaimsSet then use the lenses defined in
HasClaimsSet to set relevant claims.
For applications that use additional claims beyond those defined by RFC 7519, define a subtype and instance HasClaimsSet.
Return an empty claims set.
Methods
claimsSet :: Lens' a ClaimsSetclaimIss :: Lens' a (Maybe StringOrURI)The issuer claim identifies the principal that issued the JWT. The processing of this claim is generally application specific.
claimSub :: Lens' a (Maybe StringOrURI)The subject claim identifies the principal that is the subject of the JWT. The Claims in a JWT are normally statements about the subject. The subject value MAY be scoped to be locally unique in the context of the issuer or MAY be globally unique. The processing of this claim is generally application specific.
claimAud :: Lens' a (Maybe Audience)The audience claim identifies the recipients that the JWT is intended for. Each principal intended to process the JWT MUST identify itself with a value in the audience claim. If the principal processing the claim does not identify itself with a value in the aud claim when this claim is present, then the JWT MUST be rejected.
claimExp :: Lens' a (Maybe NumericDate)The expiration time claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of exp claim requires that the current date/time MUST be before expiration date/time listed in the exp claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew.
claimNbf :: Lens' a (Maybe NumericDate)The not before claim identifies the time before which the JWT MUST NOT be accepted for processing. The processing of the nbf claim requires that the current date/time MUST be after or equal to the not-before date/time listed in the nbf claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew.
claimIat :: Lens' a (Maybe NumericDate)The issued at claim identifies the time at which the JWT was issued. This claim can be used to determine the age of the JWT.
claimJti :: Lens' a (Maybe Text)The JWT ID claim provides a unique identifier for the JWT. The identifier value MUST be assigned in a manner that ensures that there is a negligible probability that the same value will be accidentally assigned to a different data object. The jti claim can be used to prevent the JWT from being replayed. The jti value is a case-sensitive string.
Instances1HasClaimsSet
HasClaimsSet ClaimsSetDefined in jose-0.11 · Crypto.JWT
Validate the claims made by a ClaimsSet.
You should never need to use this function directly. These checks are always performed by verifyClaims and verifyJWT. The function is exported mainly for testing purposes.
Unregistered claims (deprecated)
Deprecated. use a subtype to define additional claims
Add a non-RFC 7519 claim. Use the lenses from the HasClaimsSet class for setting registered claims.
Deprecated. use a subtype to define additional claims
Claim Names can be defined at will by those using JWTs. Use this lens to access a map non-RFC 7519 claims in the Claims Set object.
JWT errors
Constructors
JWSError ErrorA JOSE error occurred while processing the JWT
JWTClaimsSetDecodeError StringThe JWT payload is not a JWT Claims Set
JWTExpiredJWTNotYetValidJWTNotInIssuerJWTNotInAudienceJWTIssuedAtFuture
Methods
_JWTError :: Prism' r JWTError_JWSError :: Prism' r Error_JWTClaimsSetDecodeError :: Prism' r String_JWTExpired :: Prism' r ()_JWTNotYetValid :: Prism' r ()_JWTNotInIssuer :: Prism' r ()_JWTNotInAudience :: Prism' r ()_JWTIssuedAtFuture :: Prism' r ()
Instances1AsJWTError
AsJWTError JWTErrorDefined in jose-0.11 · Crypto.JWT
Miscellaneous types
Audience data. In the general case, the aud value is an array of case-sensitive strings, each containing a StringOrURI value. In the special case when the JWT has one audience, the aud value MAY be a single case-sensitive string containing a StringOrURI value.
The ToJSON instance formats an Audience with one value as a string (some non-compliant implementations require this.)
Constructors
A JSON string value, with the additional requirement that while
arbitrary string values MAY be used, any value containing a :
character MUST be a URI.
Note: the IsString instance will fail if the string
contains a : but does not parse as a URI. Use stringOrUri
directly in this situation.
Instances5Eq, Show, IsString, FromJSON, ToJSON
Eq StringOrURIDefined in jose-0.11 · Crypto.JWTShow StringOrURIDefined in jose-0.11 · Crypto.JWTIsString StringOrURIDefined in jose-0.11 · Crypto.JWTNon-total. A string with a
in it MUST parse as a URI:FromJSON StringOrURIDefined in jose-0.11 · Crypto.JWTToJSON StringOrURIDefined in jose-0.11 · Crypto.JWT
A JSON numeric value representing the number of seconds from 1970-01-01T0:0:0Z UTC until the specified UTC date/time.
Constructors
Instances5Eq, Ord, Show, FromJSON, ToJSON
Eq NumericDateDefined in jose-0.11 · Crypto.JWTOrd NumericDateDefined in jose-0.11 · Crypto.JWTShow NumericDateDefined in jose-0.11 · Crypto.JWTFromJSON NumericDateDefined in jose-0.11 · Crypto.JWTToJSON NumericDateDefined in jose-0.11 · Crypto.JWT
Re-exports
module Crypto.JOSE