Skip to content

Commit 26567d1

Browse files
committed
(TK-497) Allow requiring authorization via config setting
This commit addresses PDB-5261 which documents a transient bug that allows the metrics endpoint to be accessed without authorization when the trapperkeeper-metrics bootstrap config contains the authorization service. The root of this problem is likely a race condition within trapperkeeper. This patch adds a trapperkeeper-metrics config option metrics.metrics-webservice.jolokia.require-auth which defaults to true. In order to use the trapperkeeper-metrics service without authorization, this option must explicitly be set to false. When this option is set to true and the authorization service is not loaded, the IllegalArgumentException thrown by trapper-keeper's get-service method is purposefully unhandled and crashes the program. Helpful log messages are printed when this occurs.
1 parent 0d6f220 commit 26567d1

File tree

5 files changed

+50
-16
lines changed

5 files changed

+50
-16
lines changed

documentation/configuration.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ metrics: {
8080
# Default is true.
8181
enabled: false
8282
83+
# Enable or disable authorization for metrics endpoint
84+
# Default is true.
85+
require-auth: true
86+
8387
# Configure any of the settings listed at:
8488
# https://jolokia.org/reference/html/agents.html#war-agent-installation
8589
servlet-init-params: {

src/clj/puppetlabs/trapperkeeper/services/metrics/jolokia.clj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,10 @@
8484
{:authorized true :message ""}))]
8585
(if auth-check-fn
8686
(log/info "Metrics access control using trapperkeeper-authorization is enabled.")
87-
(log/warn "Metrics access control using trapperkeeper-authorization is disabled. Add the authorization service to the trapperkeeper bootstrap configuration file to enable it."))
87+
(log/warn (str "Metrics access control using trapperkeeper-authorization is disabled. "
88+
"To enable it, add the authorization service to the trapperkeeper bootstrap "
89+
"configuration file and set the trapperkeeper-metrics config setting "
90+
"metrics.metrics-webservice.jolokia.require-auth to true (default).")))
8891
(proxy [AgentServlet] []
8992
;; NOTE: An alternative to this method override would be to use defrecord
9093
;; to create a class that can be set as `:logHandlerClass` in the servlet

src/clj/puppetlabs/trapperkeeper/services/metrics/metrics_core.clj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
(def JolokiaApiConfig
2929
{(schema/optional-key :enabled) schema/Bool
30+
(schema/optional-key :require-auth) schema/Bool
3031
(schema/optional-key :servlet-init-params) jolokia/JolokiaConfig})
3132

3233
(def MbeansApiConfig

src/clj/puppetlabs/trapperkeeper/services/metrics/metrics_service.clj

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,21 @@
8181
options (if (nil? server)
8282
{:servlet-init-params config}
8383
{:servlet-init-params config :server-id (keyword server)})
84-
auth-service (tk-services/maybe-get-service this :AuthorizationService)
85-
auth-check-fn (if auth-service (partial tk-auth/authorization-check auth-service))]
86-
(add-servlet-handler
87-
(jolokia/create-servlet auth-check-fn)
88-
route
89-
options)))
84+
require-auth? (get-in-config [:metrics :metrics-webservice :jolokia :require-auth] true)]
85+
(if-not require-auth?
86+
(add-servlet-handler (jolokia/create-servlet nil) route options)
87+
(try
88+
(let [auth-service (tk-services/get-service this :AuthorizationService)
89+
auth-check-fn (partial tk-auth/authorization-check auth-service)
90+
servlet (jolokia/create-servlet auth-check-fn)]
91+
(add-servlet-handler servlet route options))
92+
;; Fail fast when auth is required but the auth service could not load
93+
(catch IllegalArgumentException e
94+
(log/error "metrics.metrics-webservice.jolokia.require-auth set to true (default)"
95+
"but trapperkeeper-authorization service was not found. To disable"
96+
"authorization change this setting to false.")
97+
(throw e))))))
98+
9099

91100
context)
92101

test/puppetlabs/trapperkeeper/services/metrics/metrics_service_test.clj

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363

6464
(def metrics-service-config
6565
{:metrics {:server-id "localhost"
66+
:metrics-webservice {:jolokia {:require-auth false}}
6667
:registries {:pl.test.reg {:reporters {:jmx {:enabled true}}}
6768
:pl.other.reg {:reporters {:jmx {:enabled true}}}}}
6869
:webserver {:port 8180
@@ -226,15 +227,31 @@
226227
(is (= 403 (get body "status")))))))))
227228

228229
(deftest metrics-service-with-tk-auth
229-
(testing "tk-auth works when included in bootstrap"
230-
(with-app-with-config
231-
app
232-
(conj services authorization-service/authorization-service)
233-
(merge metrics-service-config auth-config ssl-webserver-config)
234-
(let [resp (http-client/get "https://localhost:8180/metrics/v2/list" ssl-opts)]
235-
(is (= 200 (:status resp))))
236-
(let [resp (http-client/get "https://localhost:8180/metrics/v2" ssl-opts)]
237-
(is (= 403 (:status resp)))))))
230+
(let [config-with-require-auth
231+
(-> (merge metrics-service-config auth-config ssl-webserver-config)
232+
(assoc-in [:metrics :metrics-webservice :jolokia :require-auth] true))]
233+
234+
(testing "tk-auth works when included in bootstrap"
235+
(with-app-with-config
236+
app
237+
(conj services authorization-service/authorization-service)
238+
;; This test requires authentication so we need to override the require-auth
239+
;; option that is set to false in metrics-service-config
240+
config-with-require-auth
241+
(let [resp (http-client/get "https://localhost:8180/metrics/v2/list" ssl-opts)]
242+
(is (= 200 (:status resp))))
243+
(let [resp (http-client/get "https://localhost:8180/metrics/v2" ssl-opts)]
244+
(is (= 403 (:status resp))))))
245+
246+
(testing "exception occurs when require-auth option is true but auth service was not found"
247+
;; This test is like the previous, except the auth service is not listed as a dependency
248+
(is (thrown-with-msg? IllegalArgumentException
249+
#"service ':AuthorizationService' does not exist"
250+
(with-app-with-config
251+
app
252+
;; The auth service is purposefully left out here
253+
services
254+
config-with-require-auth))))))
238255

239256
(deftest metrics-v1-endpoint-disabled-by-default
240257
(testing "metrics/v1 is disabled by default, returns 404"

0 commit comments

Comments
 (0)