javascript客户端和netty服务器之间的安全websocket连接
Posted
技术标签:
【中文标题】javascript客户端和netty服务器之间的安全websocket连接【英文标题】:secure websocket connection between javascript client and netty server 【发布时间】:2017-11-21 02:10:39 【问题描述】:我正在使用 netty 框架版本 4.1.6 开发 websocket 服务器。 我正在使用来自netty example site 的示例代码 这是我的服务器源代码:
public class WebSocketServer
static final int PORT = 4466;
public static void main(String[] args)
final SslContext sslCtx;
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try
SelfSignedCertificate ssc = new SelfSignedCertificate();
sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioserverSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new WebSocketServerInitializer(sslCtx));
Channel ch = b.bind(PORT).sync().channel();
System.out.println("Open your web browser and navigate to " +
"http://127.0.0.1:" + PORT + '/');
ch.closeFuture().sync();
catch (Exception e)
// TODO Auto-generated catch block
e.printStackTrace();
finally
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
WebSocketServerInitializer 源代码:
public class WebSocketServerInitializer extends ChannelInitializer<SocketChannel>
private static final String WEBSOCKET_PATH = "/websocket";
private final SslContext sslCtx;
public WebSocketServerInitializer(SslContext sslCtx)
this.sslCtx = sslCtx;
@Override
public void initChannel(SocketChannel ch) throws Exception
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(sslCtx.newHandler(ch.alloc()));
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(65536));
pipeline.addLast(new WebSocketServerCompressionHandler());
pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true));
// pipeline.addLast(new WebSocketIndexPageHandler(WEBSOCKET_PATH));
pipeline.addLast(new WebSocketFrameHandler());
这是我的 html 代码:
<html>
<head>
<script type="text/javascript">
// Let us open a web socket
var ws = null;
function WebSocketTest()
if ("WebSocket" in window)
alert("WebSocket is supported by your Browser!");
// Let us open a web socket
ws = new WebSocket("wss://localhost:4466/websocket");
ws.onopen = function()
// Web Socket is connected, send data using send()
ws.send("Message to send");
alert("Message is sent...");
;
ws.onmessage = function (evt)
var received_msg = evt.data;
alert(received_msg);
//alert("Message is received...");
;
ws.onclose = function()
// websocket is closed.
alert("Connection is closed...");
;
window.onbeforeunload = function(event)
socket.close();
;
else
// The browser doesn't support WebSocket
alert("WebSocket NOT supported by your Browser!");
</script>
</head>
<body>
<div id="sse">
<a href="javascript:WebSocketTest()">Run WebSocket</a>
</div>
</body>
</html>
我使用 Chrome 浏览器浏览页面,当我点击网页中的链接时收到以下消息。
到 'wss://localhost:4466/websocket' 的 WebSocket 连接失败:连接建立错误:net::ERR_INSECURE_RESPONSE
根据这里的一些讨论,以及netty websocket示例代码,wss必须通过HTTPS转发。但是,当我在我的网页中更改以下 javascript 语句时:
ws = new WebSocket("wss://localhost:4466/websocket");
到
ws = new WebSocket("wss://echo.websocket.org");
它工作正常。这让我很困惑,为什么站点 echo.websocket.org 可以在没有 https 的情况下工作?为什么我的服务器不能?我的服务器源代码中是否缺少某些内容?
PS:echo.websocket.org 示例见以下网址:
http://jsbin.com/muqamiqimu/edit?js,console
【问题讨论】:
【参考方案1】:您的浏览器无法连接到您的 websocket 服务器,因为它检测到它不安全。
这是因为当浏览器尝试连接到您的服务器时,它会检查 SSL 证书。该证书基本上是证明您的服务器声称是 localhost 的权威服务器。
您的服务器通过其证书声明这一点,在您的情况下是由它自己签名的,基本上是 SelfSignedCertificate
类,它声称是 "example.com"。
这会产生 2 个问题:
您的浏览器连接到localhost
,但不是为localhost
获得证书,而是为example.com
获得1
您的浏览器不相信证书的签署者有权制作证书,导致它被拒绝。
有多种方法可以解决这个问题:
获取有效证书并将您的应用程序托管在服务器上
这将是推荐的生产解决方案,具体取决于您在哪里获得有效证书,它可能会花钱也可能不会花钱。
绕过证书警告
通过手动转到http://localhost:4466/,您可以跳过证书警告,基本上这会为证书规则添加 1 次例外,直到您重新启动浏览器
配置 google chrome 以接受 localhost 的无效证书
虽然这可能不安全(但不像关闭所有证书验证那样不安全),但它可能是在开发机器上测试 ssl 的好方法。
您可以通过转到 chrome://flags/#allow-insecure-localhost 并打开该选项来打开 localhost 的 ssl 验证。请注意,通过调用 new SelfSignedCertificate("localhost");
构造函数使用此选项时,您可能需要将证书的域设置为 localhost
。
【讨论】:
以上是关于javascript客户端和netty服务器之间的安全websocket连接的主要内容,如果未能解决你的问题,请参考以下文章
netty系列之:使用netty搭建websocket客户端