websocket wss_使用wss和HTTPS / TLS保护WebSocket的安全

websocket wss

这个博客的第50条提示,是的!

技术提示#49说明了如何使用用户名/密码和Servlet安全机制保护WebSocket的安全。 本技术提示将说明如何在WildFly上使用HTTPS / TLS保护WebSockets。

让我们开始吧!

  1. 创建一个新的密钥库:
    keytool -genkey -alias websocket -keyalg RSA -keystore websocket.keystore -validity 10950
    Enter keystore password:
    Re-enter new password:
    What is your first and last name?
      [Unknown]:  Arun Gupta
    What is the name of your organizational unit?
      [Unknown]:  JBoss Middleware
    What is the name of your organization?
      [Unknown]:  Red Hat
    What is the name of your City or Locality?
      [Unknown]:  San Jose
    What is the name of your State or Province?
      [Unknown]:  CA
    What is the two-letter country code for this unit?
      [Unknown]:  US
    Is CN=Arun Gupta, OU=JBoss Middleware, O=Red Hat, L=San Jose, ST=CA, C=US correct?
      [no]:  yes
    
    Enter key password for <websocket>
    	(RETURN if same as keystore password):
    Re-enter new password:

    使用“ websocket”作为便捷密码。

  2. 下载WildFly 8.1 ,解压缩,然后将“ websocket.keystore”文件复制到standalone/configuration目录standalone/configuration目录中。
  3. 以以下方式启动WildFly:
    ./bin/standalone.sh
  4. 使用jboss-cli连接到它:
    ./bin/jboss-cli.sh -c
  5. 将新的安全领域添加为:
    [standalone@localhost:9990 /] /core-service=management/security-realm=WebSocketRealm:add()
    {"outcome" => "success"}

    并配置它:

    [standalone@localhost:9990 /] /core-service=management/security-realm=WebSocketRealm/server-identity=ssl:add(keystore-path=websocket.keystore, keystore-relative-to=jboss.server.config.dir, keystore-password=websocket)
    {
        "outcome" => "success",
        "response-headers" => {
            "operation-requires-reload" => true,
            "process-state" => "reload-required"
        }
    }
  6. 将新的HTTPS侦听器添加为:
    [standalone@localhost:9990 /] /subsystem=undertow/server=default-server/https-listener=https:add(socket-binding=https, security-realm=WebSocketRealm)
    {
        "outcome" => "success",
        "response-headers" => {"process-state" => "reload-required"}
    }
  7. 可以从github.com/javaee-samples/javaee7-samples/tree/master/websocket/endpoint-wss获得一个简单的示例,以显示基于TLS的WebSocket安全性。 克隆工作空间并将目录更改为“ websocket / endpoint-wss”。 该示例的部署描述符具有:
    <security-constraint>
      <web-resource-collection>
        <web-resource-name>Secure WebSocket</web-resource-name>
        <url-pattern>/*</url-pattern>
      </web-resource-collection>
      <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
      </user-data-constraint>
    </security-constraint>

    这样可以确保任何传入此应用程序的请求都将自动定向到HTTPS URL。

  8. 通过提供以下命令来部署示例:
    mvn wildfly:deploy

现在访问http:// localhost:8080 / endpoint-wss重定向到https:// localhost:8080 / endpoint-wss 。 浏览器可能会抱怨自签名证书。 例如,Chrome显示以下警告:

techtip50-certificate-chrome

Safari显示以下警告:

techtip50证书

无论哪种情况,都单击“继续到本地主机”或“继续”以继续进行。 然后,建立安全的WebSocket连接。

要理解的另一个相关要点是,不能从受https保护的页面建立不安全的WebSocket连接。 例如我们示例中的以下代码:

new WebSocket("ws://localhost:8080/endpoint-wss/websocket");

将在Chrome开发者工具中引发以下异常:

[blocked] The page at 'https://localhost:8443/endpoint-wss/index.jsp' was loaded over HTTPS, but ran insecure content from 'ws://localhost:8080/endpoint-wss/websocket': this content should also be loaded over HTTPS.
Uncaught SecurityError: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.

请享用!

翻译自: https://www.javacodegeeks.com/2014/10/securing-websocket-using-wss-and-httpstls.html

websocket wss

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一些关于使用Netty实现WebSocket客户端(支持wss安全连接)的建议。 首先,您需要确保已经包含了Netty和WebSocket依赖项。然后可以按照以下步骤实现: 1. 创建一个WebSocketClientHandshaker,用于握手和建立WebSocket连接。这里我们需要使用wss连接,因此需要使用WebSocketClientHandshakerFactory创建一个以SSL/TLS方式连接的WebSocket连接。 2. 创建一个WebSocketClientHandler,处理WebSocket连接的事件。这里我们需要重写channelActive、channelInactive和channelRead0等方法,以便在连接建立、关闭和接收到消息时执行相应的操作。 3. 创建一个Bootstrap实例,用于启动客户端。设置bootstrap的group、channel、handler等属性。 4. 连接到WebSocket服务器。通过bootstrap的connect方法连接到指定的WebSocket服务器。 下面是一个简单的示例代码: ```java import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpClientCodec; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpRequestEncoder; import io.netty.handler.codec.http.HttpResponseDecoder; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.SslHandler; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame; import io.netty.handler.codec.http.websocketx.PingWebSocketFrame; import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker; import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory; import io.netty.handler.codec.http.websocketx.WebSocketFrame; import io.netty.handler.codec.http.websocketx.WebSocketFrameAggregator; import io.netty.handler.codec.http.websocketx.WebSocketVersion; import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; import io.netty.handler.codec.http.websocketx.WebSocketClientProtocolHandler; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import java.net.URI; import java.util.concurrent.TimeUnit; public class NettyWebSocketClient { private final URI uri; private final EventLoopGroup group; private Channel channel; public NettyWebSocketClient(URI uri) { this.uri = uri; this.group = new NioEventLoopGroup(); } public void connect() throws Exception { try { SslContext sslContext = SslContextBuilder.forClient() .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); WebSocketClientHandshaker handshaker = WebSocketClientHandshakerFactory.newHandshaker( uri, WebSocketVersion.V13, null, true, null); Bootstrap bootstrap = new Bootstrap() .group(group) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<Channel>() { @Override protected void initChannel(Channel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new LoggingHandler(LogLevel.DEBUG)); pipeline.addLast(new HttpClientCodec()); pipeline.addLast(new HttpObjectAggregator(65536)); pipeline.addLast(new HttpRequestEncoder()); pipeline.addLast(new HttpResponseDecoder()); pipeline.addLast(new SslHandler(sslContext.newEngine(ch.alloc(), uri.getHost(), uri.getPort()))); pipeline.addLast(new WebSocketClientProtocolHandler(handshaker)); pipeline.addLast(new WebSocketFrameAggregator(65536)); pipeline.addLast(new WebSocketClientHandler()); } }); channel = bootstrap.connect(uri.getHost(), uri.getPort()).sync().channel(); handshaker.handshake(channel).sync(); } catch (Exception e) { group.shutdownGracefully(); throw e; } } public void sendMessage(WebSocketFrame frame) { channel.writeAndFlush(frame); } public void close() { channel.writeAndFlush(new CloseWebSocketFrame()) .addListener(ChannelFutureListener.CLOSE); group.shutdownGracefully(); } private class WebSocketClientHandler extends io.netty.channel.SimpleChannelInboundHandler<Object> { @Override protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof FullHttpResponse) { FullHttpResponse response = (FullHttpResponse) msg; throw new IllegalStateException("Unexpected response (status=" + response.status() + ", content=" + response.content().toString() + ")"); } WebSocketFrame frame = (WebSocketFrame) msg; if (frame instanceof TextWebSocketFrame) { TextWebSocketFrame textFrame = (TextWebSocketFrame) frame; // 处理文本消息 System.out.println("Received Text Message: " + textFrame.text()); } else if (frame instanceof BinaryWebSocketFrame) { BinaryWebSocketFrame binaryFrame = (BinaryWebSocketFrame) frame; // 处理二进制消息 } else if (frame instanceof PingWebSocketFrame) { ctx.writeAndFlush(new PingWebSocketFrame(frame.content().retain())); } else if (frame instanceof CloseWebSocketFrame) { channel.close(); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { System.out.println("WebSocket Client disconnected!"); group.schedule(() -> { try { connect(); } catch (Exception e) { e.printStackTrace(); } }, 10, TimeUnit.SECONDS); } } } ``` 在使用时,您可以按照以下步骤: ```java URI uri = new URI("wss://your.websocket.server.com"); NettyWebSocketClient client = new NettyWebSocketClient(uri); client.connect(); // 发送消息 WebSocketFrame frame = new TextWebSocketFrame("Hello, WebSocket!"); client.sendMessage(frame); // 关闭连接 client.close(); ``` 希望这些信息能够对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值