Unable to authenticate RSocket kotlin client(ktor) to a Spring RSocket server

Viewed 15

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?

0 Answers
Related