auth0 / go-jwt-middleware

A Middleware for Go Programming Language to check for JWTs on HTTP requests
MIT License
1.09k stars 205 forks source link

Decode encrypted appSession cookie in go middleware  #292

Open skasiai opened 1 week ago

skasiai commented 1 week ago

Checklist

Description

I have a application that has a NextJs web app backed by a Go (Echo server) backend service.

From the UI/Browser if the API call goes from Browser → NextJS web app → Go Backend service. In this case I can extract the access_token and id_token from session in the web app and pass it as Authorization header when making the call to my go backend service. This works fine.

But, when from UI/Browser the API call goes directly to my go backend service, Browser → Go Backend service, in the backend service it doesn’t get the Authorization header and instead gets a encrypted Cookie that has “appSession” property. Something like this [Next-Locale=en appSession=eyJhbGciOiJkaXIi<……>YxN30…gYfzF8D6fWw<……>k2zimuwvUg.VmXY<….>unzw]

My question is how do I decrypt/parse (or somehow use) this cookie to get access_token and id_token or use this cookie somehow to call /userinfo or /oauth/token endpoints in Auth0???

I tried something in Go to try and decrypt the cookie trying to reverse engineer the way I think this gets encrypted in nextjs-auth0 library. ` // Define your initial keying material (IKM) and salt ikm := []byte("XXX") // XXX is the AUTH0_SECRET from my .env file. Based on how they suggest to setup AUTH0_SECRET here https://auth0.com/docs/quickstart/webapp/nextjs/01-login#configure-the-sdk salt := []byte("")

// Create a new HKDF instance with SHA-256 as the hash function
hkdfReader := hkdf.New(sha256.New, ikm, salt, []byte("JWE CKE"))

// Derive a key of length 32 bytes
key := make([]byte, 32)
if _, err := io.ReadFull(hkdfReader, key); err != nil {
    panic(err)
}

fmt.Printf("Derived key: %x\n", key)

jweRaw := "eyJhbGciOiJkaXIi<……>YxN30…gYfzF8D6fWw<...>k2zimuwvUg.VmXY<….>unzw" // appSession value from Cookie
jwe, err1 := jose.ParseEncrypted(jweRaw)
if err1 != nil {
    fmt.Printf("Error Failed to parse jweRaw")
}
//fmt.Printf(jwe.KeyID)
decrypted, err := jwe.Decrypt(key)
if err != nil {
    panic(err)
}
fmt.Printf(string(decrypted))

` But with this I get an error saying when trying to “Decrypt”

panic: go-jose/go-jose: error in cryptographic primitive

Is TokenExtractor provided in this library meant for this? I couldn't find an example of it.

PS: Sorry if this is not technically a bug, but the "Help and Questions" link is broken

Reproduction

From Browser make a API call directly to backend without going through nextjs webapp

Go JWT Middleware version

v2.2.2

Go version

1.23.2

skasiai commented 1 week ago

cc @developerkunal @arpit-jn Saw you guys are the maintainers of this project. Pls help with the request. Thanks

duedares-rvj commented 1 week ago

@skasiai If I understand your request correctly, I don't think the architecture is meant to allow you to decrypt the cookie.

ref: https://community.auth0.com/t/token-in-appsession-cookie-cannot-be-decoded/60591

skasiai commented 1 week ago

Then how should I go about validating the cookie and getting the auth token for that user (after I validate the cookie)?

I think the issue is nextjs-auth0 middleware creates this "appSession" encrypted cookie that go auth0 middleware is unable to decrypt/validate/parse