|
110 | 110 | :error-message error})) |
111 | 111 | (response/content-type "text/html")))))) |
112 | 112 |
|
| 113 | +(defn ^:private successful-json-body |
| 114 | + "Extracts :body from an HTTP response only when status is 2xx and body is a map. |
| 115 | + Hato with {:as :json :coerce :unexceptional} leaves :body as a raw String for |
| 116 | + non-2xx responses, which would break callers expecting a map." |
| 117 | + [response] |
| 118 | + (when (and response (<= 200 (:status response) 299)) |
| 119 | + (let [body (:body response)] |
| 120 | + (when (map? body) body)))) |
| 121 | + |
113 | 122 | (defn ^:private valid-auth-challenge? |
114 | 123 | "A 401 is only a valid OAuth challenge if it includes a www-authenticate header. |
115 | 124 | Some proxies (e.g. istio-envoy) return 401 for unsupported methods like HEAD |
|
144 | 153 | redirect-uri (format "http://localhost:%s/auth/callback" callback-port) |
145 | 154 | www-authenticate (some-> (get headers "www-authenticate") parse-www-authenticate) |
146 | 155 | ;; Step 1: Fetch resource metadata (PRM) or auth server metadata directly |
147 | | - first-meta (some-> (http/get |
148 | | - (or (:resource_metadata www-authenticate) |
149 | | - (str base-url "/.well-known/oauth-authorization-server")) |
150 | | - {:timeout 10000 |
151 | | - :throw-exceptions? false |
152 | | - :as :json}) |
153 | | - :body) |
| 156 | + first-meta (successful-json-body |
| 157 | + (http/get |
| 158 | + (or (:resource_metadata www-authenticate) |
| 159 | + (str base-url "/.well-known/oauth-authorization-server")) |
| 160 | + {:timeout 10000 |
| 161 | + :throw-exceptions? false |
| 162 | + :as :json})) |
154 | 163 | auth-server (first (:authorization_servers first-meta)) |
155 | 164 | ;; Step 2: If PRM returned authorization_servers but no token_endpoint, |
156 | 165 | ;; fetch the actual Authorization Server Metadata (RFC 8414) |
|
159 | 168 | well-known-url (str (.getScheme uri) "://" (.getAuthority uri) |
160 | 169 | "/.well-known/oauth-authorization-server" |
161 | 170 | (.getPath uri))] |
162 | | - (some-> (http/get well-known-url |
163 | | - {:timeout 10000 |
164 | | - :throw-exceptions? false |
165 | | - :as :json}) |
166 | | - :body))) |
| 171 | + (successful-json-body |
| 172 | + (http/get well-known-url |
| 173 | + {:timeout 10000 |
| 174 | + :throw-exceptions? false |
| 175 | + :as :json})))) |
167 | 176 | ;; Merge: auth server metadata takes precedence, PRM as fallback |
168 | 177 | meta (merge first-meta auth-server-meta) |
169 | 178 | base-auth-endpoint (or (:authorization_endpoint meta) |
|
0 commit comments