All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.http4k.security.OAuthPersistence.kt Maven / Gradle / Ivy

package org.http4k.security

import org.http4k.core.Request
import org.http4k.core.Response
import org.http4k.core.Status.Companion.FORBIDDEN
import org.http4k.core.Uri
import org.http4k.security.openid.IdToken

/**
 * Provides persistence for OAuth lifecycle values:
 *  - CrossSiteRequestForgeryToken - used to retrieve that authorisation code assignment responses are genuinely from the end-service.
 *  - AccessToken - provides time-limited access to protected API resources on the end-service.
 */
interface OAuthPersistence {

    /**
     * Assign a CSRF token to this OAuth auth redirection (to the end-service) response. Opportunity here to modify the
     * response returned to the user when the redirection happens.
     */
    fun assignCsrf(redirect: Response, csrf: CrossSiteRequestForgeryToken): Response

    /**
     * Retrieve the stored CSRF token for this user request
     */
    fun retrieveCsrf(request: Request): CrossSiteRequestForgeryToken?

    /**
     * Assign a nonce to this OIDC auth redirection (to the end-service) response. Opportunity here to modify the
     * response returned to the user when the redirection happens.
     */
    fun assignNonce(redirect: Response, nonce: Nonce): Response

    /**
     * Retrieve the stored nonce token for this user request
     */
    fun retrieveNonce(request: Request): Nonce?

    /**
     * opportunity to store the uri that the request was made before authentication
     * this will then be redirected back to after auth
     *
     * Be careful not to create scenarios where an open redirector is created,
     * by applications attempting some sort of phishing attack
     */
    fun assignOriginalUri(redirect: Response, originalUri: Uri): Response

    /**
     * Retrieve the stored original uri for this user request
     */
    fun retrieveOriginalUri(request: Request): Uri?

    /**
     * Assign the swapped AccessToken (and optional IdToken) returned by the end-service. Opportunity here to modify the
     * response returned to the user when the redirection happens.
     *
     * Notice that both accessToken and idToken contain the raw response from the authorization server and may
     * require extra validation before use.
     */
    fun assignToken(request: Request, redirect: Response, accessToken: AccessToken, idToken: IdToken? = null): Response

    /**
     * Retrieve the stored AccessToken token for this user request
     */
    fun retrieveToken(request: Request): AccessToken?

    /**
     * Build the default failure response which occurs when a failure occurs during the callback process (eg. a mismatch/missing
     * CSRF or failure occurring when calling into the end-service for the access-token.
     */
    fun authFailureResponse(reason: OAuthCallbackError) = Response(FORBIDDEN.description(reason.description))

    private val OAuthCallbackError.description: String
        get() = when (this) {
            is OAuthCallbackError.AuthorizationCodeMissing -> "Authorization code missing"
            is OAuthCallbackError.CouldNotFetchAccessToken -> "Failed to fetch access token (status: $status)"
            is OAuthCallbackError.InvalidCsrfToken -> "Invalid state (expected: $expected, received: $received)"
            is OAuthCallbackError.InvalidNonce -> "Invalid nonce (expected: $expected, received: $received)"
            is OAuthCallbackError.InvalidAccessToken -> "Invalid access token: $reason"
            is OAuthCallbackError.InvalidIdToken -> "Invalid id token: $reason"
        }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy