@@ -12,6 +12,7 @@ module LavinMQ
1212 Log = LavinMQ ::Log .for " http.oauth"
1313
1414 @oidc_config : Auth ::JWT ::JWKSFetcher ::OIDCConfiguration ?
15+ @oidc_mutex = Mutex .new
1516
1617 def initialize (@authenticator : Auth ::Authenticator )
1718 register_routes
@@ -112,6 +113,11 @@ module LavinMQ
112113 oauth_redirect_error(context, " OAuth not configured" ) unless config.oauth_issuer_url
113114 client_id = config.oauth_client_id || oauth_redirect_error(context, " OAuth not configured" )
114115
116+ if error = context.request.query_params[" error" ]?
117+ description = context.request.query_params[" error_description" ]? || error
118+ oauth_redirect_error(context, description)
119+ end
120+
115121 cookie_value = context.request.cookies[" oauth_state" ]?.try(& .value) || oauth_redirect_error(context, " Missing OAuth state" )
116122 sep = cookie_value.index(':' ) || oauth_redirect_error(context, " Invalid OAuth state cookie" )
117123 oauth_redirect_error(context, " State mismatch" ) unless context.request.query_params[" state" ]? == cookie_value[0 ...sep]
@@ -163,10 +169,12 @@ module LavinMQ
163169 # Cached for the lifetime of the process. OIDC endpoints are essentially
164170 # static; a server restart is needed if the IdP changes them.
165171 private def oidc_config : Auth ::JWT ::JWKSFetcher ::OIDCConfiguration
166- @oidc_config ||= begin
167- config = Config .instance
168- issuer_url = config.oauth_issuer_url || raise " OAuth issuer not configured"
169- Auth ::JWT ::JWKSFetcher .new(issuer_url, config.oauth_jwks_cache_ttl).fetch_oidc_config
172+ @oidc_mutex .synchronize do
173+ @oidc_config ||= begin
174+ config = Config .instance
175+ issuer_url = config.oauth_issuer_url || raise " OAuth issuer not configured"
176+ Auth ::JWT ::JWKSFetcher .new(issuer_url, config.oauth_jwks_cache_ttl).fetch_oidc_config
177+ end
170178 end
171179 end
172180
0 commit comments