【问题标题】:Spring RSocket over WebSocket - Access user information from HTTP sessionSpring RSocket over WebSocket - 从 HTTP 会话访问用户信息
【发布时间】:2022-01-16 16:53:05
【问题描述】:

在我的 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 发送额外的令牌.

【问题讨论】:

    标签: spring spring-security spring-webflux rsocket spring-rsocket


    【解决方案1】:

    您是否尝试过以下方法?我在文档中找到它:2.2 Secure Your RSocket Methods(可能需要向下滚动一点)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();
    }
    

    【讨论】:

    • 感谢您的回答,但不幸的是,这仅在您在启动连接之后进行身份验证时才有效,例如在启动 rsocket 连接的设置框架中。我想在进行 websocket 握手时重用可用的身份验证信息。您实际上可以在您发布的链接中看到他们正在执行此操作,在代码下方的几行代码中他们执行 setupMetadata(user, SIMPLE_AUTH),它在 rsocket 设置框架中发送身份验证信息。
    • 通常,每条消息的“消息”类应包含每个连接的唯一标识符。您可以保留一个映射(在内存中或数据库中),以将设置框架中发送的身份验证详细信息与会话匹配。 (至少,我过去就是这样做的……手头上没有代码……)
    • 我不想在设置框架中发送额外的身份验证信息。我想重用用于启动 websocket 连接(传输层)的 HTTP 会话,就像原始 websocket 的示例一样。在设置框架中发送身份验证详细信息需要在 JavaScript 中访问身份验证详细信息(或更实际的一些令牌),而我尝试使用仅限 http 的 cookie(在 JavaScript 中没有可用的令牌或身份验证详细信息)。
    猜你喜欢
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-28
    相关资源
    最近更新 更多