ktor icon indicating copy to clipboard operation
ktor copied to clipboard

authentication.formAuthentication give blank page

Open hasanOryx opened this issue 8 years ago • 5 comments

I've the below code, route "/" and "/bye" are working fine, but route "login" given blank page once!!

package blog

import kotlinx.html.*
import kotlinx.html.stream.*    // for createHTML
import org.jetbrains.ktor.application.*
import org.jetbrains.ktor.auth.*
import org.jetbrains.ktor.features.*
import org.jetbrains.ktor.http.*
import org.jetbrains.ktor.response.*
import org.jetbrains.ktor.routing.*

import org.jetbrains.ktor.request.*   // for request.uri

import org.jetbrains.ktor.html.*
import org.jetbrains.ktor.pipeline.*

import org.jetbrains.ktor.host.*   // for embededServer
import org.jetbrains.ktor.netty.*  // for Netty

fun main(args: Array<String>) {
    embeddedServer(Netty, 8080, watchPaths = listOf("BlogAppKt"), module = Application::module).start()
}

fun Application.module() {
    install(DefaultHeaders)
    install(CallLogging)

    intercept(ApplicationCallPipeline.Call) { 
        if (call.request.uri == "/hi")
            call.respondText("Test String")
    }

    install(Routing) {
        get("/") {
            call.respondText("""Hello, world!<br><a href="/bye">Say bye?</a>""", ContentType.Text.Html)
        }
        get("/bye") {
            call.respondText("""Good bye! <br><a href="/login">Login?</a> """, ContentType.Text.Html)
        }
        route("/login") {
            authentication {
                formAuthentication { up: UserPasswordCredential ->
                    when {
                        up.password == "ppp" -> UserIdPrincipal(up.name)
                        else -> null
                    }
                }
            }
         
            handle {
                val principal = call.authentication.principal<UserIdPrincipal>()
                if (principal != null) {
                    call.respondText("Hello, ${principal.name}")
                } else {
                        val html = createHTML().html {
                        body {
                            form(action = "/login", encType = FormEncType.applicationXWwwFormUrlEncoded, method = FormMethod.post) {
                                p {
                                    +"user:"
                                    textInput(name = "user") {
                                        value = principal?.name ?: ""
                                    }
                                }

                                p {
                                    +"password:"
                                    passwordInput(name = "pass")
                                }

                                p {
                                    submitInput() { value = "Login" }
                                }
                            }
                        }
                    }
                    call.respondText(html, ContentType.Text.Html)
                }
            }
        }
    }
}

hasanOryx avatar Sep 30 '17 05:09 hasanOryx

I noticed the same thing, looks like the formAuth returns a respond(Unauthorised) if the user is not logged in, which does meke sense, but I thought the handle block is meant to handle all responses for this path/location. So I'm not sure if this is a routing bug or a auth bug?

chrisjenx avatar Oct 14 '17 02:10 chrisjenx

@orangy / @cy6erGn0m you able to clarify? Looks like a bug with the handle pipeline. I don't know enough about the project yet to give a more definitive answer.

chrisjenx avatar Oct 14 '17 02:10 chrisjenx

It worked with me when I specified the names of the user and password fileds, as below:

        authentication {
            formAuthentication ("user", "pass"){ up: UserPasswordCredential ->
                when {
                    up.password == "ppp" -> UserIdPrincipal(up.name)
                    else -> null
                }
            }
        }

hasanOryx avatar Nov 06 '17 19:11 hasanOryx

Same blank page upon requesting login. I've a sample with the same route("/login") as above. when I request "/login", the handle block is never invoked. Chrome reports that it received a 401, and the server logs that it returned a 401. Breakpoints show that execution never delegates down to the above route from the interceptor of AuthenticationPipeline.formAuthentication. (ktor 0.9.0)

I believe the FormPostApplication.kt from the ktor-sample-auth sample project needs some love. Note that in the code sample at the top of this thread, the authentication pipeline is projecting both the GET and the POST, so the login form can never be rendered -- resulting in a blank result when ktor returns the 401. The youKube sample shows a functioning use of formAuthentication.

jwmach1 avatar Dec 15 '17 15:12 jwmach1

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

oleg-larshin avatar Aug 10 '20 15:08 oleg-larshin