From 3006e90126c3bed740ef2aa368586837f18b459f Mon Sep 17 00:00:00 2001 From: "Julian K. Arni" Date: Thu, 14 Apr 2022 11:03:03 +0200 Subject: [PATCH 1/3] Allow IO in JWTSettings' validationKeys --- .../src/Servant/Auth/Server/Internal/ConfigTypes.hs | 4 ++-- .../src/Servant/Auth/Server/Internal/JWT.hs | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/ConfigTypes.hs b/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/ConfigTypes.hs index 83e5784d..61e6f33a 100644 --- a/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/ConfigTypes.hs +++ b/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/ConfigTypes.hs @@ -33,7 +33,7 @@ data JWTSettings = JWTSettings -- | Algorithm used to sign JWT. , jwtAlg :: Maybe Jose.Alg -- | Keys used to validate JWT. - , validationKeys :: Jose.JWKSet + , validationKeys :: IO Jose.JWKSet -- | An @aud@ predicate. The @aud@ is a string or URI that identifies the -- intended recipient of the JWT. , audienceMatches :: Jose.StringOrURI -> IsMatch @@ -44,7 +44,7 @@ defaultJWTSettings :: Jose.JWK -> JWTSettings defaultJWTSettings k = JWTSettings { signingKey = k , jwtAlg = Nothing - , validationKeys = Jose.JWKSet [k] + , validationKeys = pure $ Jose.JWKSet [k] , audienceMatches = const Matches } -- | The policies to use when generating cookies. diff --git a/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/JWT.hs b/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/JWT.hs index 57c0630c..0c8c3c54 100644 --- a/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/JWT.hs +++ b/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/JWT.hs @@ -58,14 +58,15 @@ makeJWT v cfg expiry = runExceptT $ do verifyJWT :: FromJWT a => JWTSettings -> BS.ByteString -> IO (Maybe a) verifyJWT jwtCfg input = do - verifiedJWT <- liftIO $ runExceptT $ do + keys <- validationKeys jwtCfg + verifiedJWT <- runExceptT $ do unverifiedJWT <- Jose.decodeCompact (BSL.fromStrict input) Jose.verifyClaims (jwtSettingsToJwtValidationSettings jwtCfg) - (validationKeys jwtCfg) + keys unverifiedJWT return $ case verifiedJWT of Left (_ :: Jose.JWTError) -> Nothing Right v -> case decodeJWT v of Left _ -> Nothing - Right v' -> Just v' \ No newline at end of file + Right v' -> Just v' From 4cc714d654521e10b758f9a255ba4c2ed33c2bc5 Mon Sep 17 00:00:00 2001 From: "Julian K. Arni" Date: Thu, 14 Apr 2022 11:28:39 +0200 Subject: [PATCH 2/3] Changelog entry --- changelog.d/1580 | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 changelog.d/1580 diff --git a/changelog.d/1580 b/changelog.d/1580 new file mode 100644 index 00000000..a1adea64 --- /dev/null +++ b/changelog.d/1580 @@ -0,0 +1,10 @@ +synopsis: Allow IO in validationKeys +prs: #1580 +issues: #1579 + +description: { + +Currently validationKeys are a fixed JWKSet. This does not work for setups such +as AWS Cognito or Okta, where there is a regular key rotation. This change +alters the type of validationKeys from JWKSet to IO JWKSet. +} From 4e8fb045e2b7908cc4d21253406490cae6902d4b Mon Sep 17 00:00:00 2001 From: "Julian K. Arni" Date: Thu, 14 Apr 2022 13:53:54 +0200 Subject: [PATCH 3/3] Review fix --- changelog.d/1580 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/changelog.d/1580 b/changelog.d/1580 index a1adea64..d0587055 100644 --- a/changelog.d/1580 +++ b/changelog.d/1580 @@ -4,7 +4,9 @@ issues: #1579 description: { -Currently validationKeys are a fixed JWKSet. This does not work for setups such -as AWS Cognito or Okta, where there is a regular key rotation. This change -alters the type of validationKeys from JWKSet to IO JWKSet. +Currently validationKeys are a fixed JWKSet. This does not work with OIDC +providers such as AWS Cognito or Okta, which regularly fetching jwks_uri to +discover new and expired keys. + +This change alters the type of validationKeys from JWKSet to IO JWKSet. }