skip to content

RSocket Security & Transports

Securing RSocket means authenticating at setup or per request with metadata, authorizing routes, and choosing a TCP or WebSocket transport with resumption. Interviewers ask because a persistent connection makes 'authenticate once' subtly different from per-request auth.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

explore

questions

5

What does @EnableRSocketSecurity do, and how do you turn on security for an RSocket server in Spring?

level: juniorimportance: must knowfreq 45%

answer

  1. @EnableRSocketSecurity -> RSocketSecurity builder
  2. build() -> PayloadSocketAcceptorInterceptor bean
  3. authorizePayload + simpleAuthentication/jwt
  4. reactive only, not the HTTP filter chain
  5. forget it = wide-open RSocket

basics

~10 s

@EnableRSocketSecurity turns on Spring Security for RSocket and gives you an RSocketSecurity builder. You use it to create a PayloadSocketAcceptorInterceptor bean that defines who can connect and which routes require authentication.

solid answer

~30 s

RSocket is a binary, bidirectional messaging protocol; Spring Security secures it separately from HTTP. You add @EnableRSocketSecurity to a @Configuration class (requires the spring-security-messaging/rsocket dependency and a reactive stack). This exposes an RSocketSecurity builder that you inject to build a PayloadSocketAcceptorInterceptor bean. On that builder you call authorizePayload(...) to declare authorization rules — for example .setup().authenticated() for the connection handshake and .route("secure.*").authenticated() for message routes — and enable an authentication method like simpleAuthentication() or jwt(). Spring wires the interceptor into the RSocket acceptor so every SETUP and REQUEST payload passes through the security rules. Without @EnableRSocketSecurity, RSocket endpoints are wide open.

code

java · 22 lines
java
@Configuration
@EnableRSocketSecurity
public class RSocketSecurityConfig {

    @Bean
    PayloadSocketAcceptorInterceptor rsocketInterceptor(RSocketSecurity security) {
        security.authorizePayload(authorize -> authorize
                .setup().authenticated()
                .route("secure.*").authenticated()
                .anyRequest().authenticated()
                .anyExchange().permitAll())
            .simpleAuthentication(Customizer.withDefaults());
        return security.build();
    }

    @Bean
    MapReactiveUserDetailsService users() {
        UserDetails user = User.withDefaultPasswordEncoder()
                .username("user").password("pass").roles("USER").build();
        return new MapReactiveUserDetailsService(user);
    }
}

go deeper

for a junior

Know that @EnableRSocketSecurity exists, needs a PayloadSocketAcceptorInterceptor bean, and that RSocket is secured separately from HTTP.

for a middle

Explain the RSocketSecurity DSL (authorizePayload, setup vs route vs anyRequest) and wiring the interceptor bean.

for a senior

Discuss reactive-only nature, security context propagation via Reactor context, and pairing with an AuthenticationManager/UserDetailsService.

for a principal

Reason about securing RSocket as a first-class channel across a system, threat model of an open acceptor, and consistency with HTTP auth.

**RSocket** is an application-level, binary messaging protocol built on Reactive Streams. It supports four interaction models (request-response, fire-and-forget, request-stream, request-channel), runs over TCP or WebSocket, and is fully asynchronous and bidirectional. Because it is not HTTP, the normal Spring Security web filter chain does not apply — RSocket needs its own security integration. **@EnableRSocketSecurity** is the annotation that activates that integration. You place it on a `@Configuration` class. It requires: (1) the reactive Spring stack, and (2) `spring-boot-starter-rsocket` plus Spring Security's RSocket support (`spring-security-messaging` / `spring-security-rsocket`, pulled in transitively by the security starter). It works with the reactive `RSocketSecurity` DSL — RSocket security in Spring is reactive-only. Activating the annotation publishes an **`RSocketSecurity`** bean — a builder object. You inject it into a `@Bean` method and use it to construct a **`PayloadSocketAcceptorInterceptor`**. This interceptor is what Spring plugs into the RSocket `SocketAcceptor` so that security runs on incoming payloads. Typical minimal config: ```java @Bean PayloadSocketAcceptorInterceptor rsocketInterceptor(RSocketSecurity security) { security.authorizePayload(authorize -> authorize .anyRequest().authenticated() .anyExchange().permitAll()) .simpleAuthentication(Customizer.withDefaults()); return security.build(); } ``` Key pieces of the DSL: - **`authorizePayload(...)`** — declares authorization rules. Inside it you match on `.setup()` (the connection handshake), `.route("pattern")` (a specific `@MessageMapping` route, using Ant-style/`PathPattern` matching), `.anyRequest()` (any request payload), and `.anyExchange()` (any payload including setup and metadata pushes). - **`simpleAuthentication()` / `jwt()` / `basicAuthentication()`** — declares which authentication method to accept from metadata. **Gotchas:** - If you forget `@EnableRSocketSecurity` (or forget to return the interceptor bean), the RSocket server is unauthenticated — anyone who can open a connection can invoke any route. - RSocket security is **reactive**; there is no servlet/imperative variant. `SecurityContext` is propagated via the Reactor context, so `@MessageMapping` handlers read the principal with `ReactiveSecurityContextHolder` or an `@AuthenticationPrincipal`/`Mono<Principal>` parameter. - You also need an `AuthenticationManager` (e.g. a `MapReactiveUserDetailsService` or a JWT decoder) for the chosen authentication method to validate credentials. **When to use:** any time you expose RSocket endpoints (`@MessageMapping`) that should not be public.

  • Why can't the normal HTTP SecurityFilterChain secure RSocket endpoints?
    RSocket is a separate binary protocol over TCP/WebSocket, not HTTP request/response, so the servlet/WebFlux web filter chain never sees RSocket frames. Security is applied via a PayloadSocketAcceptorInterceptor instead.
  • How does an @MessageMapping handler read the authenticated user?
    Via the reactive security context — accept a Mono<Principal>/@AuthenticationPrincipal parameter or call ReactiveSecurityContextHolder.getContext(). The principal is propagated through the Reactor context, not a ThreadLocal.

saying these in an interview costs you the question

  • Thinking the HTTP SecurityFilterChain secures RSocket automatically
  • Believing RSocket security has an imperative (non-reactive) variant
  • Not returning the PayloadSocketAcceptorInterceptor bean, leaving endpoints open

context

open as a page

Explain the difference between securing the SETUP payload and securing REQUEST payloads in RSocket, and how you express each with RSocketSecurity.

level: middleimportance: should knowfreq 35%

basics

~10 s

The SETUP payload authenticates the connection once, when the client establishes it. REQUEST payloads authenticate individual messages/routes. In the authorizePayload DSL you use .setup() for the connection and .route(...)/.anyRequest() for per-message rules.

open as a page

How does a Spring RSocket requester present authentication metadata (simple username/password vs bearer/JWT), and how does the server validate it?

level: seniorimportance: should knowfreq 30%

basics

~20 s

The requester attaches auth metadata using a well-known RSocket mime type. For simple auth it sends a UsernamePasswordMetadata; for bearer it sends a BearerTokenMetadata (a JWT). The server enables simpleAuthentication() or jwt() on RSocketSecurity to decode and validate it.

open as a page

How do you authorize specific @MessageMapping routes in RSocket — via the authorizePayload DSL vs @PreAuthorize method security — and what are the trade-offs?

level: seniorimportance: should knowfreq 25%

basics

~10 s

You can authorize routes centrally in RSocketSecurity.authorizePayload using .route("pattern").hasRole(...), or on the handler with @PreAuthorize after enabling @EnableReactiveMethodSecurity. The DSL is connection-layer; method security is per-method and closer to the code.

open as a page

Compare RSocket's TCP and WebSocket transports in Spring, and explain what session resumption (resume) is and how it interacts with security.

level: principalimportance: nice to knowfreq 18%

basics

~20 s

RSocket runs over TCP or WebSocket. TCP is a raw framed socket (fast, internal); WebSocket tunnels through HTTP (works through browsers/proxies/firewalls). Resume lets a dropped connection reconnect and continue the same session without losing in-flight streams, using a resume token.

open as a page