1

I'm trying to implement a REST API using Kit. My routes are defined as follows:

(defn api-routes [_opts]
   ["/auth/login" {:post auth/login}]
   ["/auth/checked" {:get (wrap-auth auth/checked)}]
   ["/auth/open" {:get auth/open}]])

The /auth/login endpoint returns a signed JWT, which works fine. Now I'd like the endpoint /auth/checked to run through authenticaton, while /auth/open remains open. The endpoints don't do anything meaningful:

(defn checked [_req] {:status 200 :body "require auth"})
(defn open [_req] {:status 200 :body "without auth"})

More important is the wrap-auth function, defined as follows:

(defn wrap-auth [handler]
  (let [backend (backends/jws {:secret "topsecret"})]
    (-> handler
        (auth-middleware/wrap-authentication backend)
        (auth-middleware/wrap-authorization backend))))

With backend coming from buddy.auth.backends.

However, both endpoints work without any Authorization header.

I'm totally lost how middlewares are supposed to be applied to some routes but not to others. Any ideas how to do this?

Is there any Kit demo application that makes use of JWT bearer authentication?

I'm looking at the Kit documentation on how to restrict access but don't understand anything.

1 Answer 1

2

The Kit is irrelevant here, the relevant parts are Ring and Buddy. And according to how Ring handlers work, you have applied the middleware correctly, so we're left with just Buddy.

According to the Buddy's User Guide, this is how your underlying handler should look:

(defn my-handler
  [request]
  (if (:identity request)
    (response (format "Hello %s" (:identity request)))
    (response "Hello Anonymous")))

Notice how it uses (:identity request) - the wrap-authentication middleware sets that key is the request was successfully authenticated. Even though it's written in the "Http-Basic" section, it applies to any kind of auth that uses wrap-authentication.

As for the wrap-authorization middleware, it works only if an appropriate exception is thrown from your own handler. For the gritty details you should check out the impl of the middleware, but just to get started you can use something like (buddy.auth/throw-unauthorized).

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! I stumbled upon that, but never considered using it, because it looks like it only applies to basic auth. Unfortunately, the :identity key is always missing in my case when I do the request as follows: curl -H "Authorization: Bearer [my token]" localhost:3000/api/auth/checked.
An absence of the key means that the auth has failed, for whatever reason.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.