How to implement user authentication using clojure-liberator?
Asked Answered
S

2

8

I'm not really understanding https://github.com/clojure-liberator/liberator and the list of decision points that it provides to the developer. How would one implement a basic auth/auth service using/alongside/on-top-of the library?

Smitherman answered 4/12, 2012 at 11:36 Comment(0)
O
6

from the readme"

Resources are compatible with Ring and can be wrapped in Ring middleware. When evaluated, a resource returns a function which takes a Ring request and returns a Ring response.

so you can then wrap it in ring-basic-authentication

(use 'ring.middleware.basic-authentication)
(defn authenticated? [name pass] (and (= name "foo") (= pass "bar")))
(def app (-> routes .. (wrap-basic-authentication authenticated?))
Occultism answered 4/12, 2012 at 18:8 Comment(0)
B
14

The idiomatic way is to implement the :authorized? decision point. However there is currently no support for the handling of basic or digest authentication. A practical approach is to use ring-basic-authentication for authentication and handle only authorization in the resource. The following example uses ring-basic-authentication and sets the token to a users's role. This role is then checked by liberator in authorized?

(defresource admin-only
  :handle-ok "secrect"
  :handle-unauthorized "for admins only"
  :authorized? (fn [{{token :token} :request}]
                 (= "admin" token)))

;; token returned encodes role
(defn authenticated? [name pass] 
  (cond (and (= name "scott") 
             (= pass "tiger")) "admin")
        (and (= name "jack")
             (= pass "jill"))  "user)))

(def app (wrap-basic-authentication admin-only authenticated?))
Bicipital answered 6/1, 2013 at 21:55 Comment(4)
cone should be cond in this (very good) example, but we aren't allowed to fix typosObligatory
Typo is fixed. Thanks for the hintBicipital
I was able to manage the authentication, but not the authorization. If I pass "admin-only" to wrap-basic-authentication I get the following error "clojure.lang.ArityException: Wrong number of args (2) passed to: controller/admin-only". My route declaration is as follows: (GET "/test" request (admin-only request ). How the token gets to the resource? Thanks.Huang
In the latest version of wrap-basic-authentication authenticated? return is filled in request :basic-authentication. So to get it's necessary to do the following :authorized? #(get-in % [:request :basic-authentication])):Huang
O
6

from the readme"

Resources are compatible with Ring and can be wrapped in Ring middleware. When evaluated, a resource returns a function which takes a Ring request and returns a Ring response.

so you can then wrap it in ring-basic-authentication

(use 'ring.middleware.basic-authentication)
(defn authenticated? [name pass] (and (= name "foo") (= pass "bar")))
(def app (-> routes .. (wrap-basic-authentication authenticated?))
Occultism answered 4/12, 2012 at 18:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.