úÎoçl'      !"#$%& Safe-Inferred'()*+'()*'()*+ experimental Stefan Saasen <stefan@saasen.me>None"^The JWT Claims Set represents a JSON object whose members are the claims conveyed by the JWT. EThe iss (issuer) claim identifies the principal that issued the JWT. QThe sub (subject) claim identifies the principal that is the subject of the JWT. »The aud (audience) claim identifies the audiences that the JWT is intended for according to draft 18 of the JWT spec, the aud claim is option and may be present in singular or as a list. ¶The exp (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. Its value MUST be a number containing an IntDate value. iThe nbf (not before) claim identifies the time before which the JWT MUST NOT be accepted for processing. KThe iat (issued at) claim identifies the time at which the JWT was issued. AThe jti (JWT ID) claim provides a unique identifier for the JWT. FJWT Header, describes the cryptographic operations applied to the JWT /The typ (type) Header Parameter defined by [JWS] and [JWE] is used to - declare the MIME Media Type [IANA.MediaTypes] of this complete JWT in 3 contexts where this is useful to the application. 7 This parameter has no effect upon the JWT processing. 7The cty (content type) Header Parameter defined by [JWS] and [JWE] is L used by this specification to convey structural information about the JWT. MThe alg (algorithm) used for signing the JWT. The HS256 (HMAC using SHA-256) R is the only required algorithm and the only one supported in this implementation  in addition to none- which means that no signature will be used. See  Hhttp://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-23#page-6 "HMAC using SHA-256 hash algorithm @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 [RFC3986]. StringOrURI values are ? compared as case-sensitive strings with no transformations or  canonicalizations applied. =A JSON numeric value representing the number of seconds from 3 1970-01-01T0:0:0Z UTC until the specified UTC date/time. The JSON Web Token 3JSON Web Token that has been successfully verified .JSON Web Token without signature verification 6The secret used for calculating the message signature -Extract the claims set from a JSON Web Token )Extract the header from a JSON Web Token 5Extract the signature from a verified JSON Web Token =Return the seconds since 1970-01-01T0:0:0Z UTC for the given  +Encode a claims set using the given secret :{  let5 cs = def { -- def returns a default JWTClaimsSet iss = stringOrURI "Foo"W , unregisteredClaims = Map.fromList [("http://example.com/is_root", (Bool True))] } key = secret "secret-key" in encodeSigned HS256 key cs:}’"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZSwiaXNzIjoiRm9vIn0.vHQHuG3ujbnBUmEp-fSUtYxk27rLiP2hrNhxpyWhb2E"'Encode a claims set without signing it :{  let5 cs = def { -- def returns a default JWTClaimsSet iss = stringOrURI "Foo" , iat = intDate 1394700934T , unregisteredClaims = Map.fromList [("http://example.com/is_root", (Bool True))] } in encodeUnsigned cs:}~"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjEzOTQ3MDA5MzQsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlLCJpc3MiOiJGb28ifQ."GDecode a claims set without verifying the signature. This is useful if I information from the claim set is required in order to verify the claim H (e.g. the secret needs to be retrieved based on unverified information  from the claims set). :{ let‚ input = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U" :: T.Text mJwt = decode input in fmap header mJwt:}DJust (JWTHeader {typ = Just "JWT", cty = Nothing, alg = Just HS256})and :{ let‚ input = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U" :: T.Text mJwt = decode input in fmap claims mJwt:}¸Just (JWTClaimsSet {iss = Nothing, sub = Nothing, aud = Nothing, exp = Nothing, nbf = Nothing, iat = Nothing, jti = Nothing, unregisteredClaims = fromList [("some",String "payload")]})SUsing a known secret and a decoded claims set verify that the signature is correct . and return a verified JWT token as a result. VThis will return a VerifiedJWT if and only if the signature can be verified using the  given secret. VThe separation between decode and verify is very useful if you are communicating with T multiple different services with different secrets and it allows you to lookup the U correct secret for the unverified JWT before trying to verify it. If this is not an M isuse for you (there will only ever be one secret) then you should just use   . :{ let‚ input = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U" :: T.Text" mUnverifiedJwt = decode input? mVerifiedJwt = verify (secret "secret") =<< mUnverifiedJwt in signature =<< mVerifiedJwt:}>Just (Signature "Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U") XDecode a claims set and verify that the signature matches by using the supplied secret. 6 The algorithm is based on the supplied header value. LThis will return a VerifiedJWT if and only if the signature can be verified  using the given secret. :{ let‚ input = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U" :: T.Text< mJwt = decodeAndVerifySignature (secret "secret") input in signature =<< mJwt:}>Just (Signature "Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U")!3Try to extract the value for the issue claim field ! from the web token in JSON form "$Create a Secret using the given key E This will currently simply wrap the given key appropriately buy may I return a Nothing in the future if the key needs to adhere to a specific & format and the given key is invalid. # Convert the ,+ into an IntDate. Returns a Nothing if the J argument is invalid (e.g. the NominalDiffTime must be convertible into a 9 positive Integer representing the seconds since epoch). $ Convert a - into a . Returns a Nothing if the ; String cannot be converted (e.g. if the String contains a : but is  *not* a valid URI). % Convert a  into a -. Returns the T.Text C representing the String as-is or a Text representation of the URI  otherwise. & Convert the  claim in a  into a ` [StringOrURI]` C. / 0123456 !"#$%&789:;<=>?@ABCDEFGHI)JK  !"#$%&* !"&#$%   ..  / 1024356 !"#$%&789:;<=>?@ABCDEFGHIL      !"#$%&'()*+,-./01234 56789:;<=>?@ABCDEFGHIJKLMNLMOP jwt-0.5.0Web.JWT Web.Base64 JWTClaimsSetisssubaudexpnbfiatjtiunregisteredClaims JWTHeadertypctyalg AlgorithmHS256 StringOrURIIntDateJWT VerifiedJWT UnverifiedJWT SignatureSecretJSONclaimsheader signaturesecondsSinceEpoch encodeSignedencodeUnsigneddecodeverifydecodeAndVerifySignature tokenIssuersecretintDate stringOrURIstringOrURIToTextauds base64Decode base64Encode base64Encode'removePaddingBase64Encoding operateOnText time-1.4.0.1Data.Time.Clock.UTCNominalDiffTime text-0.11.3.1Data.Text.InternalText ClaimsMapUSVerified Unverified encodeJWTparseJWTdottedcalculateDigest fromHashMapremoveRegisteredClaims$fFromJSONStringOrURI$fToJSONStringOrURI$fFromJSONAlgorithm$fToJSONAlgorithm$fFromJSONIntDate$fToJSONIntDate$fToJSONJWTHeader$fFromJSONJWTHeader$fFromJSONJWTClaimsSet$fToJSONJWTClaimsSet$fDefaultJWTClaimsSet$fDefaultJWTHeader$fShowStringOrURIdata-default-class-0.0.1Data.Default.ClassdefDefault