https://kotlinlang.org logo
#http4k
Title
# http4k
d

Dmitry Kandalov

03/01/2024, 1:18 PM
What would be a canonical implementation of
OAuthPersistence
? I can see there is
FakeOAuthPersistence
and
InsecureCookieBasedOAuthPersistence
but it’s not too clear to me what a real implementation should do blob smile Or
FakeOAuthPersistence
and
CustomOAuthPersistence
are good enough?
🙌 1
❤️ 1
d

dave

03/01/2024, 1:22 PM
example: for Okta or other SSO with JWTs it's basically implementing assignXXX and retrieveXXX. For a standard webapp it's going to be setting cookies or getting the values out of them.
for JWT validations - assign and issue token would issue or validate the JWT content
We'd normally use something like KMS for signing the JWT content, and using the KMS public key for verification
suggest Nimbus/Jose for the JWT stuff
d

Dmitry Kandalov

03/01/2024, 2:09 PM
for Okta or other SSO with JWTs it’s basically implementing assignXXX and retrieveXXX
This sounds like
FakeOAuthPersistence
and
CustomOAuthPersistence
🤔
d

dave

03/01/2024, 2:12 PM
well probably - I didn't check.
you could also of course back the store with something like redis etc...
because you don't want to store (say) access tokens for the end resource in the JWT
it depends on if you're just needing auth or for the app to talk to a third party like github
d

Dmitry Kandalov

03/01/2024, 2:13 PM
I’m really just trying to understand what it supposed to do conceptually. It’s just auth via SSO.
Copy code
class CustomOAuthPersistence : OAuthPersistence {
    var nonce: Nonce? = null
    var csrf: CrossSiteRequestForgeryToken? = null
    var accessToken: AccessToken? = null
    var originalUri: Uri? = null

    override fun retrieveCsrf(request: Request): CrossSiteRequestForgeryToken? = csrf

    override fun assignCsrf(redirect: Response, csrf: CrossSiteRequestForgeryToken): Response {
        this.csrf = csrf
        return redirect.header("action", "assignCsrf")
    }

    override fun assignNonce(redirect: Response, nonce: Nonce): Response {
        this.nonce = nonce
        return redirect.header("action", "assignNonce")
    }

    override fun retrieveNonce(request: Request): Nonce? = nonce

    override fun assignOriginalUri(redirect: Response, originalUri: Uri): Response {
        this.originalUri = originalUri
        return redirect.header("action", "assignOriginalUri")
    }

    override fun retrieveOriginalUri(request: Request): Uri? = originalUri

    override fun retrieveToken(request: Request): AccessToken? = accessToken

    override fun assignToken(
        request: Request,
        redirect: Response,
        accessToken: AccessToken,
        idToken: IdToken?
    ): Response {
        this.accessToken = accessToken
        return redirect.header("action", "assignToken")
    }
}
d

dave

03/01/2024, 2:14 PM
well that of course isn't doing any validation of the callback
and the fake one probably puts the accesstoken into the cookie instead of issuing a JWT
(it's very insecure :))
d

Dmitry Kandalov

03/01/2024, 2:16 PM
FakeOAuthPersistence
is the same as the code above.
d

dave

03/01/2024, 2:17 PM
if you want secure - take the state that you need, encode and encrypt it into the state parameter then on the callback you can compare the values to check it's the same
that's stateless from your perspective - use the redirect as the storage
d

dave

03/03/2024, 12:10 PM
yeah - that's the basis of the versions we use, then plug in JWT infra
2 Views