Add support for parsing JSON Web Key Sets
This commit is contained in:
committed by
Steve Chávez
parent
dadfe965b9
commit
473ac70789
@@ -35,7 +35,7 @@ import PostgREST.ApiRequest ( ApiRequest(..), ContentType(..)
|
||||
, mutuallyAgreeable
|
||||
, userApiRequest
|
||||
)
|
||||
import PostgREST.Auth (jwtClaims, containsRole, parseJWK)
|
||||
import PostgREST.Auth (jwtClaims, containsRole, parseSecret)
|
||||
import PostgREST.Config (AppConfig (..))
|
||||
import PostgREST.DbStructure
|
||||
import PostgREST.DbRequestBuilder( readRequest
|
||||
@@ -65,7 +65,7 @@ import Protolude hiding (intercalate, Proxy)
|
||||
postgrest :: AppConfig -> IORef (Maybe DbStructure) -> P.Pool -> IO UTCTime -> IO () -> Application
|
||||
postgrest conf refDbStructure pool getTime worker =
|
||||
let middle = (if configQuiet conf then id else logStdout) . defaultMiddle
|
||||
jwtSecret = parseJWK <$> configJwtSecret conf in
|
||||
jwtSecret = parseSecret <$> configJwtSecret conf in
|
||||
|
||||
middle $ \ req respond -> do
|
||||
time <- getTime
|
||||
|
||||
+20
-10
@@ -16,7 +16,7 @@ module PostgREST.Auth (
|
||||
containsRole
|
||||
, jwtClaims
|
||||
, JWTAttempt(..)
|
||||
, parseJWK
|
||||
, parseSecret
|
||||
) where
|
||||
|
||||
import Control.Lens.Operators
|
||||
@@ -43,7 +43,7 @@ data JWTAttempt = JWTInvalid JWTError
|
||||
Receives the JWT secret and audience (from config) and a JWT and returns a map
|
||||
of JWT claims.
|
||||
-}
|
||||
jwtClaims :: Maybe JWK -> Maybe StringOrURI -> LByteString -> UTCTime -> Maybe JSPath -> IO JWTAttempt
|
||||
jwtClaims :: Maybe JWKSet -> Maybe StringOrURI -> LByteString -> UTCTime -> Maybe JSPath -> IO JWTAttempt
|
||||
jwtClaims _ _ "" _ _ = return $ JWTClaims M.empty
|
||||
jwtClaims secret audience payload time jspath =
|
||||
case secret of
|
||||
@@ -83,17 +83,27 @@ containsRole :: JWTAttempt -> Bool
|
||||
containsRole (JWTClaims claims) = M.member "role" claims
|
||||
containsRole _ = False
|
||||
|
||||
parseJWK :: ByteString -> JWK
|
||||
parseJWK str =
|
||||
fromMaybe (hs256jwk str) (JSON.decode (toS str) :: Maybe JWK)
|
||||
{-|
|
||||
Parse `jwt-secret` configuration option and turn into a JWKSet.
|
||||
|
||||
There are three ways to specify `jwt-secret`: text secret, JSON Web Key
|
||||
(JWK), or JSON Web Key Set (JWKS). The first two are converted into a JWKSet
|
||||
with one key and the last is converted as is.
|
||||
-}
|
||||
parseSecret :: ByteString -> JWKSet
|
||||
parseSecret str =
|
||||
fromMaybe (maybe secret (\jwk' -> JWKSet [jwk']) maybeJWK)
|
||||
maybeJWKSet
|
||||
where
|
||||
maybeJWKSet = JSON.decode (toS str) :: Maybe JWKSet
|
||||
maybeJWK = JSON.decode (toS str) :: Maybe JWK
|
||||
secret = JWKSet [jwkFromSecret str]
|
||||
|
||||
{-|
|
||||
Internal helper to generate HMAC-SHA256. When the jwt key in the
|
||||
config file is a simple string rather than a JWK object, we'll
|
||||
apply this function to it.
|
||||
Internal helper to generate a symmetric HMAC-SHA256 JWK from a text secret.
|
||||
-}
|
||||
hs256jwk :: ByteString -> JWK
|
||||
hs256jwk key =
|
||||
jwkFromSecret :: ByteString -> JWK
|
||||
jwkFromSecret key =
|
||||
fromKeyMaterial km
|
||||
& jwkUse ?~ Sig
|
||||
& jwkAlg ?~ JWSAlg HS256
|
||||
|
||||
@@ -209,7 +209,7 @@ readOptions = do
|
||||
|## base url for swagger output
|
||||
|# server-proxy-uri = ""
|
||||
|
|
||||
|## choose a secret to enable JWT auth
|
||||
|## choose a secret, JSON Web Key (or set) to enable JWT auth
|
||||
|## (use "@filename" to load from separate file)
|
||||
|# jwt-secret = "foo"
|
||||
|# secret-is-base64 = false
|
||||
|
||||
Reference in New Issue
Block a user