greenpau / caddy-security

šŸ” Authentication, Authorization, and Accounting (AAA) App and Plugin for Caddy v2. šŸ’Ž Implements Form-Based, Basic, Local, LDAP, OpenID Connect, OAuth 2.0 (Github, Google, Facebook, Okta, etc.), SAML Authentication. MFA/2FA with App Authenticators and Yubico. šŸ’Ž Authorization with JWT/PASETO tokens. šŸ”
https://authcrunch.com/
Apache License 2.0
1.41k stars 70 forks source link

question: Is it possible to pass the jwt token upstream? #173

Open maemigh opened 1 year ago

maemigh commented 1 year ago

A clear and concise description of what you want to accomplish. Is it possible to pass the JWT token upstream to a reverse proxy? I'm not finding any variable that I can use in the header_up directive.

greenpau commented 1 year ago

@maemigh , typically your JWT token will be in a cookie. Are you looking for reading the token from a cookie and adding it as a header (e.g. Authorization)?

maemigh commented 1 year ago

I am not very well versed in JWT tokens, but everything Iā€™ve read so far seems to have suggested that they are passed in the Authorization header (or otherwise doesnā€™t really explain it while assuming it is known).

I see it in the cookie now, so I think I can figure it out from here. Do you think it would make sense to mention in the docs that this is where caddy-security sets it?

My particular use-case is to use caddy-security with ldap, and then use the token with grafanaā€™s jwt auth. I am not sure if what I am trying to do is weird or not, but the only other option I see is to use the authproxy approach, but that doesnā€™t seem very secure since I canā€™t guarantee a specific IP for the whitelist.

greenpau commented 1 year ago

I am not very well versed in JWT tokens, but everything Iā€™ve read so far seems to have suggested that they are passed in the Authorization header (or otherwise doesnā€™t really explain it while assuming it is known).

@maemigh , it really depends. Once you authenticate with auth portal, the JWT is then stored in a cookie. That cookie is then sent to upstream.

My particular use-case is to use caddy-security with ldap, and then use the token with grafanaā€™s jwt auth. I am not sure if what I am trying to do is weird or not, but the only other option I see is to use the authproxy approach, but that doesnā€™t seem very secure since I canā€™t guarantee a specific IP for the whitelist.

See the comments here: https://github.com/greenpau/caddy-security/issues/131#issuecomment-1171723189 and https://github.com/greenpau/caddy-security/issues/105

maemigh commented 1 year ago

This may help the other users from the comments you mentioned. I was able to get JWT logins working with Grafana using auth.jwt instead of auth.proxy

Snippets from Caddyfile, this is not all inclusive but contains the directives needed to get JWT working using the keys generated by following examples from https://authp.github.io/docs/authorize/token-verification

authentication portal myportal {
            crypto default token lifetime 3600
            crypto key verify from file /path/here/caddy_sign_key.pem
}
authorization policy mypolicy {
            allow roles authp/admin authp/user
            crypto key sign-verify from file /path/here/caddy_sign_key.pem
}

exampleserver.com {
        redir /grafana /grafana/
    handle_path /grafana/* {
        authorize with mypolicy
        reverse_proxy {
            to https://grafanaserverexamplehere.com
            header_up X-JWT-Assertion {http.request.cookie.access_token}
        }
}

From grafana.ini

[auth.jwt]
enabled = true
header_name = X-JWT-Assertion
;email_claim = sub
email_claim = email
username_claim = sub
;jwk_set_url = https://foo.bar/.well-known/jwks.json
jwk_set_file = /etc/grafana/jwks.json

jwks.json can be set as a local file or it can be set up on the Caddy server (a PEM to JWK converter can create it from the public key). The verify key in PEM form should also work with the key_file directive as well.

greenpau commented 1 year ago

@maemigh , nicely done! šŸ‘