@@ -67,6 +67,10 @@ import PostgREST.SchemaCache.Identifiers (QualifiedIdentifier (..),
6767 toQi )
6868
6969import Protolude hiding (Proxy , toList )
70+ import Web.OIDC.Client (Provider (.. ), discover )
71+ import Network.HTTP.Client.TLS (newTlsManager )
72+ import Network.HTTP.Client (HttpException (InvalidUrlException ))
73+ import Control.Arrow ((***) , (&&&) )
7074
7175audMatchesCfg :: AppConfig -> Text -> Bool
7276audMatchesCfg = maybe (const True ) (==) . configJwtAudience
@@ -247,6 +251,7 @@ readAppConfig dbSettings optPath prevDbUri roleSettings roleIsolationLvl = do
247251 decodeLoadFiles parsedConfig = try $
248252 decodeJWKS =<<
249253 decodeSecret =<<
254+ oidcConnectDiscovery =<<
250255 readSecretFile =<<
251256 readDbUriFile prevDbUri parsedConfig
252257
@@ -478,6 +483,18 @@ parser optPath env dbSettings roleSettings roleIsolationLvl =
478483 defaultServerHost :: Maybe Text -> Text
479484 defaultServerHost = fromMaybe " !4"
480485
486+ oidcConnectDiscovery :: AppConfig -> IO AppConfig
487+ oidcConnectDiscovery conf = maybe (pure conf) (performDiscovery . decodeUtf8) (configJwtSecret conf)
488+ where
489+ performDiscovery uri = oidcDiscover uri `catches` [
490+ Handler (\ case
491+ InvalidUrlException _ _ -> pure conf
492+ _ -> fail " OIDC discovery failed" )
493+ ]
494+ oidcDiscover uri = do
495+ manager <- newTlsManager
496+ (Provider _ keys) <- discover uri manager
497+ pure $ conf { configJWKS = Just $ JWT. JwkSet keys }
481498-- | Read the JWT secret from a file if configJwtSecret is actually a
482499-- filepath(has @ as its prefix). To check if the JWT secret is provided is
483500-- in fact a file path, it must be decoded as 'Text' to be processed.
0 commit comments