1

在我的 Web 应用程序中,用户使用用户名/密码组合登录并获取会话 cookie。在发起 WebSocket 连接时,我可以很方便地访问 中的用户信息WebSocketHandler,例如:

@Component
public class MyWebSocketHandler implements WebSocketHandler {
    @Override
    public Mono<Void> handle(WebSocketSession session) {
        // two ways to access security context information, either like this:
        Mono<Principal> principal = session.getHandshakeInfo().getPrincipal();

        // or like this
        Mono<SecurityContext> context = ReactiveSecurityContextHolder.getContext();

        //...
        return Mono.empty();
    }
}

两者都重用了来自 WebSocket 握手的 HTTP 会话,我不必通过 WebSocket 本身发送额外的身份验证。STOMP 同样适用:我可以重用 HTTP 会话的信息。

如何使用 RSocket 实现相同的目标?例如,我如何在这样的 MessageMapping 方法中获取有关用户的信息?:

@Controller
public class RSocketController {
    @MessageMapping("test-stream")
    public Flux<String> streamTest(RSocketRequester requester) {
        // this mono completes empty, no security context available :(
        Mono<SecurityContext> context = ReactiveSecurityContextHolder.getContext();

        return Flux.empty();
    }
}

我找到了许多如何使用 RSocket 设置身份验证的资源,但是它们都依赖于在 WebSocket 连接建立后的附加身份验证,但我特别想重用 Web 会话并且不想通过 WebSocket 发送额外的令牌。

4

1 回答 1

0

您是否尝试过以下操作?我在文档中找到它:2.2 保护您的 RSocket 方法(可能需要向下滚动一点)https://spring.io/blog/2020/06/17/getting-started-with-rsocket-spring-security

@PreAuthorize("hasRole('USER')") // (1)
@MessageMapping("fire-and-forget")
public Mono<Void> fireAndForget(final Message request, @AuthenticationPrincipal UserDetails user) { // (2)
    log.info("Received fire-and-forget request: {}", request);
    log.info("Fire-And-Forget initiated by '{}' in the role '{}'", user.getUsername(), user.getAuthorities());
    return Mono.empty();
}
于 2022-01-24T20:06:57.663 回答