当前位置: 首页 > 知识库问答 >
问题:

Spring WebFlux通过身份验证的WebSocket连接

奚正谊
2023-03-14

我正在运行带有公开WebSocketendpoint的Spring Boot@2.2.x服务器。下面是我的WebSocketConfiguration:

@Slf4j
@Configuration
public class WebSocketConfiguration {

    private static final String WS_PATH = "/ws/notifications";

    @Bean
    public HandlerMapping webSocketHandlerMapping() {
        Map<String, WebSocketHandler> handlersMap = new HashMap<>();
        handlersMap.put(WS_PATH, session -> session.send(session.receive()
                                                                .map(WebSocketMessage::getPayloadAsText)
                                                                .doOnEach(logNext(log::info))
                                                                .map(msg -> format("notification for your msg: %s", msg))
                                                                .map(session::textMessage)));

        SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
        handlerMapping.setOrder(Ordered.HIGHEST_PRECEDENCE);
        handlerMapping.setUrlMap(handlersMap);
        return handlerMapping;
    }

    @Bean
    public WebSocketHandlerAdapter handlerAdapter(WebSocketService webSocketService) {
        return new WebSocketHandlerAdapter(webSocketService);
    }

    @Bean
    public WebSocketService webSocketService() {
        return new HandshakeWebSocketService(new ReactorNettyRequestUpgradeStrategy());
    }
}

问题是如何使用基本身份验证承载身份验证access_token查询参数实现建立WS连接的身份验证?

更好的选择是避免使用Spring Security。

多谢了。

共有1个答案

郎泰平
2023-03-14

Websocket连接以升级的HTTP请求开始。您可以在升级发生之前进行JWT令牌身份验证。在spring boot中,它的工作方式如下:

公开自定义的WebSocketServicebean

@Bean
public WebSocketService webSocketService(RequestUpgradeStrategy upgradeStrategy) {
    return new HandshakeWebSocketService(upgradeStrategy);
}

在您自己的类中实现RequestUpgradeStrategy接口:

@Override
public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler, @Nullable String subProtocol, Supplier<HandshakeInfo> handshakeInfoFactory) {
    ServerHttpResponse response = exchange.getResponse();
    HttpServerResponse reactorResponse = getNativeResponse(response);
    HandshakeInfo handshakeInfo = handshakeInfoFactory.get();
    NettyDataBufferFactory bufferFactory = (NettyDataBufferFactory) response.bufferFactory();

    var authResult = validateAuth(handshakeInfo);
    if (authResult == unauthorised) return Mono.just(reactorResponse.status(rejectedStatus))
                                               .flatMap(HttpServerResponse::send);
    else return reactorResponse.sendWebsocket(subProtocol, //
                                              this.maxFramePayloadLength,//
                                              (in, out) -> {
                                                  ReactorNettyWebSocketSession session = new ReactorNettyWebSocketSession(in, out,
                                                                                                                          handshakeInfo,
                                                                                                                          bufferFactory,
                                                                                                                          this.maxFramePayloadLength);
                                                  return handler.handle(session);
                                              });
}

返回ReactorResponse.sendWebSocket是将连接升级为WebSocket连接的现有行为

可以返回ReactorResponse.Status以停止正在升级的连接。例如,在未经授权的连接情况下,可以返回401响应。

查询参数和身份验证头可以在握手信息中找到。如何进行身份验证本身不在问题的范围之内。

 类似资料:
  • 问题内容: 问题: 我们有一个基于Spring MVC的RESTful API,其中包含敏感信息。该API应该是安全的,但是不希望随每个请求一起发送用户凭证(用户/密码组合)。根据REST准则(和内部业务要求),服务器必须保持无状态。该API将由另一台服务器以mashup方式使用。 要求: 客户端使用凭据向(不受保护的URL)发出请求;服务器返回一个安全令牌,该令牌包含足够的信息供服务器验证未来的

  • 我们想使用Jitsi REST API创建一个会议。我们的Jitsi实例已经受到Prosody的保护:只有某些用户可以主持会议(他们必须使用用户和密码凭据进行身份验证才能主持会议室)。现在,在他们这么做之后,计划是通过创建一个来宾密码来保护房间,聊天伙伴/来宾需要输入该密码才能加入会议。这个过程需要通过REST API实现自动化:我们希望通过REST API创建会议,并传递一个需要来宾输入的密码。

  • 一切都一直在工作,只是今天我开始得到一个错误消息,我甚至不能从Android工作室“同步项目与Gradle文件”。我唯一改变的是...办公室:D

  • 我只是在两个问题中输入,然后程序似乎继续没有问题。但是,我需要这些代码通过cron任务实现自动化,所以我不希望它暂停程序来问我这两个问题。是不是有什么东西我不提供给它,这样它就不会问这个了?我需要做些什么来阻止它的追问?希望有人有一些想法。多谢了。

  • 问题: 我们有一个spring的基于MVC的RESTful API,它包含敏感信息。API应该是安全的,但是不希望在每个请求中发送用户的凭据(User/Pass组合)。根据REST指南(和内部业务需求),服务器必须保持无状态。API将由另一台服务器以混搭方式使用。 要求: > 客户端请求使用凭据(不受保护的URL);服务器返回一个安全令牌,该令牌包含足够的信息,供服务器验证未来的请求并保持无状态。

  • 问题内容: 我一直在努力用Spring-Security 正确实现Stomp(websocket) 身份验证 和 授权 。 为了后代,我将回答我自己的问题以提供指导。 问题 Spring WebSocket文档(用于身份验证)看起来不清楚ATM(IMHO)。而且我不明白如何正确处理 身份验证 和 授权 。 我想要的是 使用登录名/密码对用户进行身份验证。 防止匿名用户通过WebSocket连接。