I've created a Spring RSocket server to provide for my kotlin ktor app realtime updates. Without authentication the kotlin client is able to connect to the stream and receive updates. When I configured to the server basic auth using RSocket Spring Security I couldn't make it work on the kotlin client side anymore.
Kotlin side
This is the code I use to request the stream:
var flow = rSocket.requestStream(buildPayload {
data(ByteArray(0))
compositeMetadata {
add(SimpleAuthMetadata("app", "xrOMMKj2jyaf4vH9RC6w"))
add(RoutingMetadata("api.v1.messages.events.stream/qQYISR9xcmR8ZtVHNgg1lbYgSQcxafPqPW0ZbE0yaA6ham6n54"))
}
})
flow.onEach {
println(it.data.readText())
}.collect()
The code above throws the exception io.rsocket.kotlin.RSocketError$Setup$Rejected: Access Denied when requesting the stream.
Obs: After configuring security on the server side, the only change I made to the client was add the SimpleAuthMetadata
to the composite metadata. There is no much documentation about it so I don't know if this is right or if there are additional configurations left to do.
The only way I able to make it work on the client side was add to it the spring rsocket dependencies.
RSocketRequester configuration:
@Configuration
class RsocketConfiguration {
@Bean
fun rSocketRequester(rsocketRequesterBuilder: RSocketRequester.Builder): RSocketRequester? {
val authenticationMimeType: MimeType =
MimeTypeUtils.parseMimeType(WellKnownMimeType.MESSAGE_RSOCKET_AUTHENTICATION.string)
val credentials = UsernamePasswordMetadata("app", "xrOMMKj2jyaf4vH9RC6w")
return rsocketRequesterBuilder
.rsocketStrategies { builder -> builder.encoder(SimpleAuthenticationEncoder()) }
.setupMetadata(credentials, authenticationMimeType)
.connectWebSocket(URI.create("ws://localhost:8080/rsocket")).block()
}
}
Stream request:
scope.launch {
rSocketRequester
.route("api.v1.messages.events.stream/{userId}", "qQYISR9xcmR8ZtVHNgg1lbYgSQcxafPqPW0ZbE0yaA6ham6n54")
.retrieveFlow<EventMessage>()
.collect {
println(it.webhookId)
}
}
Unfortunately, since the consumer(client side) is a ktor app I can't simply add the spring dependencies. Is there a way to make it work using the dependencies provided for kotlin?