Created
October 20, 2010 18:55
-
-
Save raek/637053 to your computer and use it in GitHub Desktop.
HTTP Basic Authentication Ring Middleware
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns se.raek.rhea.auth | |
(:use [ring.util.codec :only (base64-decode)])) | |
(defn parse-credentials | |
"Extracts the user name and password from a HTTP Basic Authentication header | |
value and returns them in a vector. | |
Example: | |
(parse-credentials \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\") | |
=> [\"Aladdin\" \"open sesame\"]" | |
[auth-header-value] | |
{:pre [(or (nil? auth-header-value) | |
(string? auth-header-value))]} | |
(when auth-header-value | |
(when-let [[_ creds-b64] | |
(re-find #"^[Bb][Aa][Ss][Ii][Cc] (.*)$" auth-header-value)] | |
(let [creds-string (String. (base64-decode creds-b64) "US-ASCII")] | |
(when-let [[_ user pass] | |
(re-find #"^([^:]*):(.*)$" creds-string)] | |
[user pass]))))) | |
(defn wrap-basic-auth | |
"Decorator for HTTP Basic Authentication. This middleware sets the given key | |
to the value returned by auth-fn when called with the username and password | |
as arguments. auth-fn should take two arguments, the username and the | |
password, and return something that identifies the user, if the credentials | |
are valid." | |
[handler auth-fn] | |
(fn [{:keys [headers], :as request}] | |
(if-let [[user pass] (parse-credentials (get headers "authorization"))] | |
(handler (assoc request :user (auth-fn user pass))) | |
(handler (assoc request :user nil))))) | |
(defn wrap-require-auth | |
[handler realm] | |
(let [realm-string (format "Basic realm=\"%s\"" realm) | |
entity-string (format "Authentication Required for Realm \"%s\"" realm)] | |
(fn [{:keys [user], :as request}] | |
(if user | |
(handler request) | |
{:status 401 | |
:headers {"WWW-Authenticate" realm-string | |
"Content-Type" "text/plain"} | |
:body entity-string})))) | |
(defn reset-auth | |
[realm] | |
(let [realm-string (format "Basic realm=\"%s\"" realm)] | |
(fn [request] | |
{:status 401 | |
:headers {"WWW-Authenticate" realm-string | |
"Content-Type" "text/plain"} | |
:body "Use this page to force your browser to ask for credentials"}))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment