ktor
ktor copied to clipboard
Add OAuth2/Space client authentication
Subsystem Client
Is your feature request related to a problem? Please describe. There is no oauth2 client authentication, and especially JetBrains Space auth
Describe the solution you'd like I'd like to have smth like
val spaceClient = client.config {
Auth {
Space(clientId, clientSecret)
}
}
actually to authenticate in Space I have to do smth like
private data class AccessToken(val token_type: String, val expires_in: Int, val access_token: String)
private suspend fun issueAccessToken(endpoint: String, clientId: String, clientSecret: String): AccessToken {
return client.submitForm(
url = "${endpoint}/oauth/token",
formParameters = Parameters.build {
append("grant_type", "client_credentials")
append("scope", "**")
}
) {
header(
HttpHeaders.Authorization,
HttpAuthHeader.Single(
AuthScheme.Basic,
String(Base64.getEncoder().encode("$clientId:$clientSecret".toByteArray()))
).render()
)
}
}
and later on for each query use
private fun HttpRequestBuilder.authHeader() {
header(
HttpHeaders.Authorization,
HttpAuthHeader.Single(issueAccessToken.token_type, issueAccessToken.access_token).render()
)
}
Motivation to include to ktor OAuth2 is quite common auth way
I tried to write my own OAuthAuthProvider
based on the existing providers in io.ktor.client.features.auth.providers
which seems to work but with the restriction that I can only retry a request once.
But I might need to retry the request multiple times when using a refresh token:
- try request
- request fails with 401
- the provider is asked to add an authentication-header
- it does by adding the current access token
- request is retried with the added header by the auth-feature
- request fails again because the token is invalid
- now the provider should
- invalidate the current access token
- get a new access token (via refresh token or username/password)
- retry the request one more time with the new access token
- request is ok or fails again (start over or stop)
So my question is: How can I retry the request multiple times in an io.ktor.client.features.auth.AuthProvider
?
PS: When my provider is working, I'm happy to contribute it here.
Hi, @hardysim. You can try using ‘HttpSend’ feature. You can add interceptor there and retry request multiple times(See HttpRedirect feature as the example)
I've managed to alter the Auth
feature to behave a bit like OkHttp's Authenticator
.
This means, AuthProvider.addRequestHeaders()
can return a nullable request (instead of just altering it) and Auth
will execute()
the request if one is returned (and stops when null
is returned). This way, no circuitBreaker
is needed and the provider can retry the request as often as it likes to.
I'm going to post a PR with my changes. Maybe the team will accept my solution and you'll get my OAuthAuthProvider
with it.
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.
To crosslink the progress:
- #1740 contains the
OAuthAuthProvider
but was only merged into a private branch by @e5l - #1733 contains an additional constant
AuthScheme.Bearer
which is needed byOAuthAuthProvider
but is not merged yet - I've used both in production since I've posted both and they're working fine so I'd be happy if both can me accepted and added to the master-branch.
Is there any update regarding this issue?
Please follow https://youtrack.jetbrains.com/issue/KTOR-5232/