From 4d170ef8330380b6285b9192b56768a32fc744d3 Mon Sep 17 00:00:00 2001 From: Maxim Koltsov Date: Wed, 9 Jun 2021 15:10:21 +0300 Subject: [PATCH] version 0.1.3.6: default expiration for OIDC (#26) --- CHANGELOG.md | 5 ++++ src/Web/Template/Servant/Auth.hs | 39 ++++++++++++++++++++------------ web-template.cabal | 2 +- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c98433..8e04db5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.1.3.6] - 2021-06-09 +### Changed +- Add default expiration time for OIDC discovery document and JWKS when provider does not set + expiration. + ## [0.1.3.5] - 2021-06-08 ### Changed - CBDINFRA-318: added OpenID Connect authorization support for servant; diff --git a/src/Web/Template/Servant/Auth.hs b/src/Web/Template/Servant/Auth.hs index abaa172..2a23ceb 100644 --- a/src/Web/Template/Servant/Auth.hs +++ b/src/Web/Template/Servant/Auth.hs @@ -42,8 +42,8 @@ import Data.OpenApi.Internal (ApiKeyLocation (..), ApiKeyPara SecurityScheme (..), SecuritySchemeType (..)) import Data.OpenApi.Lens (components, description, security, securitySchemes) import Data.OpenApi.Operation (allOperations, setResponse) -import Data.Time.Clock (UTCTime, diffUTCTime, getCurrentTime, - nominalDiffTimeToSeconds) +import Data.Time.Clock (NominalDiffTime, UTCTime, addUTCTime, diffUTCTime, + getCurrentTime, nominalDiffTimeToSeconds) import Network.HTTP.Client (Manager, httpLbs) import Network.HTTP.Client.TLS (newTlsManager) import Network.HTTP.Types.Header (hContentType) @@ -120,13 +120,21 @@ instance HasOpenApi api => HasOpenApi (CbdAuth :> api) where data OIDCAuth -- | Info needed for OIDC authorization & key cache -data OIDCConfig = OIDCConfig - { oidcManager :: Manager -- ^ https manager - , oidcClientId :: Text -- ^ audience - , oidcIssuer :: URI -- ^ discovery uri - , oidcDiscoCache :: Cache () Discovery -- ^ cache - storing discovery information - , oidcKeyCache :: Cache () JWKSet -- ^ cache - storing validation keys - } +data OIDCConfig + = OIDCConfig + { oidcManager :: Manager + -- ^ https manager + , oidcClientId :: Text + -- ^ audience + , oidcIssuer :: URI + -- ^ discovery uri + , oidcDiscoCache :: Cache () Discovery + -- ^ cache - storing discovery information + , oidcKeyCache :: Cache () JWKSet + -- ^ cache - storing validation keys + , oidcDefaultExpiration :: NominalDiffTime + -- ^ Default expiration time for discovery document and JWKS + } defaultOIDCCfg :: MonadIO m => m OIDCConfig defaultOIDCCfg = do @@ -139,6 +147,7 @@ defaultOIDCCfg = do , oidcKeyCache = keyCache , oidcIssuer = error "discovery uri not set" , oidcClientId = error "client id not set" + , oidcDefaultExpiration = 10 * 60 -- 10 minutes } instance ( HasServer api context @@ -187,9 +196,11 @@ instance ( HasServer api context getToken :: Request -> Maybe ByteString getToken r = lookup "Authorization" (requestHeaders r) >>= stripPrefix "Bearer " - expiration :: UTCTime -> Maybe UTCTime -> Maybe TimeSpec - expiration now ex = diffTime - <$> (ex <|> pure now) + expiration :: UTCTime -> Maybe UTCTime -> NominalDiffTime -> Maybe TimeSpec + expiration now ex defaultExp = diffTime + <$> (ex <|> pure (addUTCTime defaultExp now)) + -- If expiration is not set by OIDC provider, cache data for some + -- default amount of time, to avoid too many requests. <*> pure now where tTreshold = 60 -- consider token expired 'tTreshold' seconds earlier @@ -221,7 +232,7 @@ instance ( HasServer api context discoSuccess disco mbDiscoExp = liftIO $ do now <- getCurrentTime - Cache.insert' oidcDiscoCache (expiration now mbDiscoExp) () disco + Cache.insert' oidcDiscoCache (expiration now mbDiscoExp oidcDefaultExpiration) () disco return disco getJWKSet :: OIDCConfig -> Discovery -> DelayedIO JWKSet @@ -237,7 +248,7 @@ instance ( HasServer api context where keysSuccess jwkSet mbKeysExp = liftIO $ do now <- getCurrentTime - Cache.insert' oidcKeyCache (expiration now mbKeysExp) () jwkSet + Cache.insert' oidcKeyCache (expiration now mbKeysExp oidcDefaultExpiration) () jwkSet return jwkSet getClaims :: OIDCConfig -> SignedJWT -> JWKSet -> DelayedIO ClaimsSet diff --git a/web-template.cabal b/web-template.cabal index b74ca6f..8bc1538 100644 --- a/web-template.cabal +++ b/web-template.cabal @@ -1,5 +1,5 @@ name: web-template -version: 0.1.3.5 +version: 0.1.3.6 synopsis: Web template description: Web template includes: