Open Unisay opened 6 years ago
signingKey
is only used in makeJWT
, which you can decide just to never call. So for now you'll need to call defaultJWTSettings
with a key to generate the signing key, but it would never be used.
Thank you, I understand that the approach you suggested would work. Do you regard it as a long term solution or as a temporary workaround?
(The first think that comes to mind is to model signingKey
as Maybe Jose.JWT
)
I don't want to answer in @domenkozar's name, so this is just my personal opinion: I think we're always open to improvements. So if you have an idea for making this a little less confusing and maybe a little more elegant, we'd be interested in hearing about it. Always. :-)
+1 for this. I think it's a common enough pattern that the service issuing the auth token might be different than the services validating the auth token, in which case you don't want to require the private key being onboard the validating services.
@domenkozar could we add this to the README somewhere?
signingKey is only used in makeJWT, which you can decide just to never call. So for now you'll need to call defaultJWTSettings with a key to generate the signing key, but it would never be used.
that's what I suspected but I'm glad I found this ticket to confirm.
Actually I'm confused again:
(n ~ S (S Z), HasServer (AddSetCookiesApi n api) ctxs, AreAuths auths ctxs v, HasServer api ctxs, AddSetCookies n (ServerT api Handler) (ServerT (AddSetCookiesApi n api) Handler), ToJWT v, HasContextEntry ctxs CookieSettings, HasContextEntry ctxs JWTSettings) => HasServer (Auth auths v :> api :: Type) ctxs
Why does v
(in Auth auths v
) need to be ToJWT
?
From skimming the code it looks like the HasServer
instance will set some cookies with the newly encoded JWT. How can I work around this and/or recover the original JWT (ideally without adding an IORef to the Context)?
Relatedly, I validate another service's JWTs, and I do so by polling for their signing key because it occasionally changes.
Is there a way to define Context '[TVar JWTSettings]
so that I can validate JWTs based on an updateable key?
Or another way of addressing this, short of restarting the WAI app every time the key changes?
Had the same use case, this might help: https://github.com/deckgo/deckdeckgo/blob/4c61f0f366e15cf5097bb947294d519473d92b85/infra/firebase-login/src/Servant/Auth/Firebase.hs#L53
@nmattia Thanks! I've been trying to get this to work for the past day, and, whew. Servant. Tough Types.
In the end, I just used endpoints authed by Auth auths User
An uninhabited type like data TVarJWT
A fn like tVarJwtAuthCheck :: FromJWT usr => TVar JWTSettings -> AuthCheck usr
and an IsAuth
instance like:
instance FromJWT usr => IsAuth TVarJWT usr where
type AuthArgs TVarJWT = '[TVar JWTSettings]
runAuth _ _ = tVarJwtAuthCheck
The one catch with doing things this way Servant's instance for HasServer ... Auth auths a :> sub
requires HasContextEntry
for CookieSettings
and JWTSettings
, meaning, even if you don't want them, you have to have them if you want to use the whole Auth auths User
pattern.
I started writing a more general HasServer
instance, but got super swamped. So. Hopefully this helps a future person mired in types.
Yes, this is all a bit too strict to our taste, and there's a "roadmap" to address this: https://summer.haskell.org/ideas.html#servant-auth-improvements
In the microservice infrastructure I am developing JWT tokens are issued by microservice
A
and validated by microservicesB
andC
. When developingB
andC
I wan't to configureservant-auth-server
to only validate tokens and never sign. Given howJWTSettings
data type is defined (signingKey
is mandatory) - I don't see how I could achieve my goal:The questions are: How is it possible to address aforementioned use-case with the current state of the code, and if its not possible, would you consider validation-only use-case to be implemented in the future?