KTOR has to be setup with two things:
SwitchUserFilter will send a redirect (HTTP 302) that we need to ignore. For this a HttpResponseValidator needs to be configured.
Auth needs to be removed similar to the comment from @Delta_George
HttpClient(OkHttp) {
HttpResponseValidator {
// for 302 don't react - so we can switch user successfully. If we follow, this doesn't work anymore.
validateResponse { response ->
val statusCode = response.status.value
val originCall = response.call
if (statusCode < 300 || originCall.attributes.contains(ValidateMark)) {
return@validateResponse
}
val exceptionCall = originCall.save().apply {
attributes.put(ValidateMark, Unit)
}
val excResp = exceptionCall.response
val excRespTxt = excResp.readText()
when (statusCode) {
302 -> {} // do nothing on "Found" statuscode
in 300..399 -> throw RedirectResponseException(excResp, excRespTxt)
in 400..499 -> throw ClientRequestException(excResp, excRespTxt)
in 500..599 -> throw ServerResponseException(excResp, excRespTxt)
else -> throw ResponseException(excResp, excRespTxt)
}
}
}
... // other configurations
}
and impersonate(...)
:
suspend fun impersonate(impersonateWithUser: PersonEntity): Impersonation<PersonEntity> {
return runCatching {
val toImpersonate = impersonateWithUser.login.replace(Regex("^\\+"), "%2B")
client.get<HttpResponse>("$BASE_URL/login/impersonate?username=${toImpersonate}") // with baseauth again
}.map {
when (it.status) {
HttpStatusCode.Found -> {
client.feature(Auth)!!.providers.removeAll { true }
Impersonation.ok(impersonateWithUser)
}
else -> Impersonation.failure(impersonateWithUser, it)
}
}.getOrElse {
Log.e(TAG, "impersonate: ", it)
Impersonation.communicationError(impersonateWithUser, it)
}
}
to end the impersonation you call the respective endpoint given in SwitchUserFilter on the serverside.