My backend on 401 sets the `www-authenticate` head...
# ktor
u
My backend on 401 sets the
www-authenticate
header this way
OAuth2 realm="WSO2 API Manager", error="invalid_token", error_description="The access token expired"
-- It doesn't contain the
Bearer
scheme, therefore
refreshTokens
in ktor client doesnt work Any way to workaround this? Changing the backend is unfortunatelly not an option
image.png
a
You can define a new authentication provider class by implementing the
AuthProvider
interface and delegating to
BearerAuthProvider
except for the
isApplicable
method:
Copy code
class MyProvider(private val delegate: BearerAuthProvider, private val realm: String?): AuthProvider {
    @Deprecated("Please use sendWithoutRequest function instead")
    override val sendWithoutRequest: Boolean
        get() = delegate.sendWithoutRequest

    override fun sendWithoutRequest(request: HttpRequestBuilder): Boolean {
        return delegate.sendWithoutRequest(request)
    }

    override suspend fun addRequestHeaders(request: HttpRequestBuilder, authHeader: HttpAuthHeader?) {
        delegate.addRequestHeaders(request, authHeader)
    }

    override fun isApplicable(auth: HttpAuthHeader): Boolean {
        if (auth.authScheme !in listOf("Bearer", "OAuth2")) {
            return false
        }
        val isSameRealm = when {
            realm == null -> true
            auth !is HttpAuthHeader.Parameterized -> false
            else -> auth.parameter("realm") == realm
        }
        return isSameRealm
    }
}
The actual configuration of the provider could look like this:
Copy code
val client = HttpClient(CIO) {
    install(Auth) {
        val realm = ""
        providers.add(MyProvider(
            BearerAuthProvider(
                refreshTokens = { BearerTokens("", "") },
                loadTokens = { BearerTokens("", "") },
                sendWithoutRequestCallback = { true },
                realm = realm
            ),
            realm
        ))
    }
}