Skip to content

Commit a76dd57

Browse files
committed
Make r.m.authorization/parse-authorization public
Make the existing ring.middleware.authorization/parse-authorization function public and make it take the Authorization header value as input. According to RFC 7235 Section 2 and RFC 9110 Section 11, the value credentials of the Authorization HTTP request header has the same structure as each of the comma-separated challenges of the WWW-Authenticate HTTP response header, which allows to reuse this function also for parsing responses: * https://datatracker.ietf.org/doc/html/rfc7235#section-2 * https://datatracker.ietf.org/doc/html/rfc9110#section-11
1 parent 990a379 commit a76dd57

File tree

2 files changed

+34
-27
lines changed

2 files changed

+34
-27
lines changed

src/ring/middleware/authorization.clj

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,16 @@
1616
{}
1717
(str/split auth-params #"\s*,\s*")))
1818

19-
(defn- parse-authorization [request]
19+
(defn parse-credentials
20+
"Parse credentials as used in the Authorization header of an HTTP
21+
request.
22+
23+
Note: The WWW-Authenticate header of an HTTP response contains a
24+
comma-separated list of challenges, which each happen to have the same
25+
structure as the single credentials in the Authorization header."
26+
[credentials]
2027
(when-let [[auth-scheme token-or-params]
21-
(some-> (get-in request [:headers "authorization"])
22-
(str/split #"\s" 2))]
28+
(some-> credentials (str/split #"\s" 2))]
2329
(cond
2430
(empty? token-or-params)
2531
{:scheme (str/lower-case auth-scheme)}
@@ -37,7 +43,7 @@
3743
[request]
3844
(if (:authorization request)
3945
request
40-
(assoc request :authorization (parse-authorization request))))
46+
(assoc request :authorization (parse-credentials (get-in request [:headers "authorization"])))))
4147

4248
(defn wrap-authorization
4349
"Parses the Authorization header in the request map, then assocs the result

test/ring/middleware/authorization_test.clj

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,44 @@
22
(:require [clojure.test :refer :all]
33
[ring.middleware.authorization :refer :all]))
44

5-
(deftest test-authorization-request
6-
(testing "pre-existing authorization"
7-
(is (= "TEST"
8-
(-> {:headers {"authorization" "Basic"}
9-
:authorization "TEST"}
10-
authorization-request
11-
:authorization))))
5+
(deftest test-parse-authorization
126
(testing "no authorization"
13-
(is (nil? (-> {:headers {}}
14-
authorization-request
15-
:authorization))))
7+
(is (nil? (parse-credentials nil))))
168
(testing "scheme without token"
179
(is (= {:scheme "basic"}
18-
(-> {:headers {"authorization" "Basic"}}
19-
authorization-request
20-
:authorization))))
10+
(parse-credentials "Basic"))))
2111
(testing "scheme with zero-length token"
2212
(is (= {:scheme "basic"}
23-
(-> {:headers {"authorization" "Basic "}}
24-
authorization-request
25-
:authorization))))
13+
(parse-credentials "Basic "))))
2614
(testing "token68"
2715
(is (= {:scheme "basic"
2816
:token "dGVzdA=="}
29-
(-> {:headers {"authorization" "Basic dGVzdA=="}}
30-
authorization-request
31-
:authorization))))
17+
(parse-credentials "Basic dGVzdA=="))))
3218
(testing "auth-params, some malformed"
3319
(is (= {:scheme "digest"
3420
:params {"a" "B"
3521
"c" "d"
3622
"eeee" "dGVzdA=="
37-
"k" "1"}}
38-
(-> {:headers {"authorization" "Digest A=B, c=\"d\",
39-
eeee=\"dGVzdA==\", fparam=dGVzdA==, g, \"h\"=i, =j, = ,, , k=1"}}
23+
"k" "1"
24+
"l" "234"}}
25+
(parse-credentials "Digest A=B, c=\"d\",
26+
eeee=\"dGVzdA==\", fparam=dGVzdA==, g, \"h\"=i, =j, = ,, , k=1, l = \"234\"")))))
27+
28+
(deftest test-authorization-request
29+
(testing "pre-existing authorization"
30+
(is (= "TEST"
31+
(-> {:headers {"authorization" "Basic"}
32+
:authorization "TEST"}
4033
authorization-request
41-
:authorization)))))
34+
:authorization))))
35+
(testing "no authorization"
36+
(is (nil? (-> {:headers {}}
37+
authorization-request
38+
:authorization))))
39+
(testing "with authorization"
40+
(is (some? (-> {:headers {"authorization" "Basic"}}
41+
authorization-request
42+
:authorization)))))
4243

4344
(deftest test-wrap-authorization-none
4445
(let [handler (wrap-authorization (fn [req respond _] (respond req)))

0 commit comments

Comments
 (0)