Inability to pass extra opts to jwt/unsign
lopezvit opened this issue · comments
The method jwt/unsign
receives a third argument called opts
. But when the method is called in the src/charmander/core.clj file it does it with the literal {:alg :rs256}
making it impossible to pass other options like:
skip-validation
max-age
iss
aud
now
leeway
Also, it would be convenient to check for :iss
and not just for :aud
/:projectid
, as that is what the firebase documentation is saying. Basically once :aud
has been validated against the regex, you would just need to make sure that :iss
is equal to "https://securetoken.google.com/" + :aud
.
@lopezvit thanks for opening this issue. You're 100% spot on. I've made the following changes:
-
Aligned validation to guideline here https://firebase.google.com/docs/auth/admin/verify-id-tokens
charmander/src/charmander/core.clj
Lines 83 to 90 in 353af2f
-
Allowed optional parameter to passed through to
jwt/unsign
If you're happy I'll push a snapshot for you to test with.
Thanks for your fast response.
I was planning to copy the code and just modify it myself, but since you have done the effort of modifying the library, I will use it as it is :)
Awesome give the snapshot a spin: [alekcz/charmander "1.0.2-SNAPSHOT"]
. Will run a few tests today then push 1.0.2 a bit later.
I have also write an issue in #funcool/buddy-auth#89 because it would be awesome that your library could be used directly with buddy-auth, as it would solve all the problems I'm facing authenticating my app with firebase token.
Do you think it could be possible to add another public method that would only return the correct public key given a token?
something like:
(defn- get-token-payload
"Retrieves payload from token. Payload is used for validation when not unsigning the message"
[token]
(let [token-array (str/split token #"\." 3)]
(json/read-value (base64/decode (pad-token (second token-array))) mapper)))
(defn- return-keys
"2nd Core library method. Validates token using projectid-regex and checks the times are correct. and returns public key."
[projectid-regex token opts]
(let [header (get-token-header token)
cert (keys/str->public-key ((keyword (:kid header)) @public-keys))
unsigned-data (if (keys/public-key? cert) (get-token-payload token) nil)
validated? (validate-claims unsigned-data)]
(when validated?
(verify-domain projectid-regex (format-result unsigned-data))
cert)))
; public methods
(defn get-secret
"Public method that makes sure the issuing domain is valid using a regex but return a public key instead of validating
the signature, to use it with buddy-auth"
[projectid-regex token]
(try
(if (nil? @public-keys)
(do (load-public-keys threadpool schedule-public-key-update) (return-keys projectid-regex token))
(return-keys projectid-regex token))
(catch Exception _ nil)))
(defn validate-token
"Public method that validates token and makes sure the issuing domain is also valid"
[projectid-regex token & opts]
(try
(if (nil? @public-keys)
(do (load-public-keys threadpool schedule-public-key-update) (authenticate projectid-regex token (merge {} opts)))
(authenticate projectid-regex token (merge {} opts)))
(catch Exception _ nil)))
That way it will be easy to create a wrapper around get-secret
that would receive only the token.
Important note: My code hasn't been tested, it is just to show what I meant.
Pushed v1.0.2