-
Notifications
You must be signed in to change notification settings - Fork 3
/
jwt.clj
66 lines (58 loc) · 2.27 KB
/
jwt.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
(ns clojure-commons.jwt
(:use [clojure.java.io :only [file]]
[medley.core :only [remove-vals]]
[slingshot.slingshot :only [try+]])
(:require [buddy.core.keys :as keys]
[buddy.sign.jws :as jws]
[clj-time.core :as time]
[clojure.string :as string]
[clojure-commons.exception-util :as cx-util]))
(defn build-default-assertion
[validity-window-end {:keys [user email given-name family-name common-name]}]
(let [now (time/now)]
(remove-vals nil?
{:sub user
:exp (time/plus now (time/seconds validity-window-end))
:iat now
:email email
:given_name given-name
:family_name family-name
:name common-name})))
(defn generator
([opts]
(generator build-default-assertion opts))
([assertion-builder {:keys [validity-window-end private-key-path private-key-password alg]}]
(let [private-key (keys/private-key private-key-path private-key-password)]
(fn [user]
(jws/sign (assertion-builder validity-window-end user)
private-key
{:alg alg})))))
(defn- list-keys
[accepted-keys-dir]
(when-not (string/blank? accepted-keys-dir)
(map str (filter #(.isFile %) (.listFiles (file accepted-keys-dir))))))
(defn- load-public-keys
[public-key-path accepted-keys-dir]
(for [path (cons public-key-path (list-keys accepted-keys-dir))]
(keys/public-key path)))
(defn- check-key
[key alg assertion]
(try+
(jws/unsign assertion key {:alg alg})
(catch [:cause :signature] _ nil)))
(defn- unsign-assertion
[accepted-keys alg assertion]
(or (first (remove nil? (map #(check-key % alg assertion) accepted-keys)))
(throw (ex-info "Untrusted JWT signature."
{:type :validation :cause :signature}))))
(defn validator
[{:keys [public-key-path accepted-keys-dir alg]}]
(let [accepted-keys (load-public-keys public-key-path accepted-keys-dir)]
(partial unsign-assertion accepted-keys alg)))
(defn user-from-default-assertion
[jwt]
{:user (:sub jwt)
:email (:email jwt)
:given-name (:given_name jwt)
:family-name (:family_name jwt)
:common-name (:name jwt)})