ktorio / ktor

Framework for quickly creating connected applications in Kotlin with minimal effort
https://ktor.io
Apache License 2.0
13.09k stars 1.07k forks source link

Handle fail authentication #366

Closed stanbar closed 6 years ago

stanbar commented 6 years ago

Hello. How to handle failed authentication (for BasicAuthenication) ? my Pipeline looks like:

install(Routing) {
        authentication {
            basicAuthentication(myRealm.name) { credentials ->
                if (!SecurityUtils.getSubject().isAuthenticated) {
                    try {
                        val token = UsernamePasswordToken(credentials.name, credentials.password)
                        SecurityUtils.getSubject().login(token)
                    } catch (e: Exception) {
                        ...
                        return@basicAuthentication null
                    }
                }
                return@basicAuthentication IdPrincipal(SecurityUtils.getSubject().principal as Long)

            }
            post("/login") {
                val currentUserId = call.principal<IdPrincipal>()?.id
                    val user = userService.findUserById(currentUserId)
                    if (user != null)
                        call.respond(HttpStatusCode.OK, user)
                    else
                        call.respond(HttpStatusCode.InternalServerError, "Could not find user after successful login")
                } 
            }
        }
}

And I would like to be able to respond to failed authentication (case where basicAuthentication return null), something like call.respond(HttpStatusCode.Forbidden,"Could not authenticate your credentials")

cy6erGn0m commented 6 years ago

Basic auth should respond Unauthorized (with challenge header) not Forbidden. Do you mean that you want to customize default behaviour or it simply doesn't respond with unauthorized?

android10 commented 3 years ago

You can use StatusPages plugin to respond appropriately to any failure state. It does also let respond to:

-exceptions- Configures response based on mapped exception classes.
-status- Configures response to status code value.
-statusFile- Configures standard file response from classpath.

In your case this you can do something like this:

install(StatusPages) {
    status(HttpStatusCode.Unauthorized) {
        call.respond(HttpStatusCode.Unauthorized, "Your Response Object")
    }
}

Do not forget to pass in the same HttpStatusCode.Unauthorized, cause otherwise you are turning this into a 200.