Maciek Murawski
Maciek Murawski

Reputation: 444

Intercept initial Ktor authenticate route

I'm trying to set up ktor oauth to work with GitHub oauth for GitHub App.

I want to authenticate users after installing GitHub App, so I checked Request user authorization (OAuth) during installation checkbox in GitHub config. This feature will take the Callback URL and sends initial request to it. The thing is, it has to be the same as redirect URL in the oauth process (urlProvider in ktor auth config).

My auth config:

install(Authentication) {
    oauth("auth-oauth-github") {
        urlProvider = { "$ngrokUrl/gh/oauth/callback" }
        providerLookup = {
            OAuthServerSettings.OAuth2ServerSettings(
                name = "github",
                authorizeUrl = "https://github.com/login/oauth/authorize",
                accessTokenUrl = "https://github.com/login/oauth/access_token",
                requestMethod = HttpMethod.Post,
                clientId = System.getenv("GITHUB_CLIENT_ID"),
                clientSecret = System.getenv("GITHUB_CLIENT_SECRET"),
                passParamsInURL = true,
                defaultScopes = listOf("user:email"),
            )
        }
        client = httpClient
    }
}
routing {
    authenticate("auth-oauth-github") {
        get("/gh/oauth/callback") {
            // need to check some parameters for initial request
            // and later for the second request need to retrieve principal
        }
    }
}

Problem I have is that I had to analyze parameters from the initial request from GitHub, but the ktor auth will automatically redirects to the authorizeUrl.

My questions are:

Upvotes: 0

Views: 860

Answers (1)

Aleksei Tirman
Aleksei Tirman

Reputation: 6999

Unfortunately, it's not possible to disable a redirect to authorizeUrl using the OAuthAuthenticationProvider. You can add an interceptor for the authenticate route to inject your code just before authentication (redirect) happens.

authenticate("auth-oauth-github") {
    val phase = PipelinePhase("MyPhase")
    insertPhaseBefore(Authentication.AuthenticatePhase, phase)
    intercept(phase) {
        // Do your processing here
        // call.request contains data for the initial request
    }

    // ...
}

Upvotes: 1

Related Questions