如何在java桌面应用程序中编写安全的websocket服务器

时间:2016-03-19 18:28:08

标签: java websocket server desktop-application embedded-jetty

我有一个Java桌面应用程序,这个应用程序启动一个用Java编写的安全websocket服务器。现在它正在使用自签名证书,该证书要求Web浏览器用户手动接受自签名证书,以便能够启动与同一websocket服务器的客户端连接。

我有一个类似" mydomain.com"这样的域的SSL证书,我想使用该SSL证书来启动Java Desktop Application的安全websocket。当然,计算机必须将该域指向本地计算机,因此我将127.0.0.1 mydomain.com添加到我的HOSTS文件(我在Windows中)。即便如此,它也无法正常工作。

所以问题是:

  

是否可以使用此Java创建安全Websocket服务器   桌面应用程序,以便在我的本地浏览器尝试访问时   wss://mydomain.com/appservices它像往常一样接受证书   (鉴于HOSTS文件修改)?,如果可以,我该怎么办   给出以下示例代码吗?

当前代码的其他信息和示例

以下是在我的Java Desktop App中启动安全websocket服务器的代码:

package com.mydomain.desktopclient.websockets.server;

import com.mydomain.desktopclient.resources.ResourceLoader;
import com.mydomain.desktopclient.websockets.server.endpoint.RequestServerEndpoint;
import org.eclipse.jetty.server.*;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;

import javax.websocket.server.ServerContainer;
import java.net.URL;

public class SecureWebSocketServer {

    Server server = null;

    public void start() throws Exception {
        server = new Server();
        int httpsPort = 443;

        URL keystore = ResourceLoader.getLocalResourceURL("/resources/misc/keystore/keystore.jks");
        SslContextFactory sslContextFactory = new SslContextFactory();
        sslContextFactory.setKeyStorePath(keystore.toExternalForm());
        sslContextFactory.setCertAlias("mydomain.com.key");
        sslContextFactory.setKeyStorePassword("keystorepass");
        sslContextFactory.setKeyManagerPassword("keymanagerpass");
        sslContextFactory.addExcludeProtocols("SSLv3");
        sslContextFactory.addExcludeCipherSuites(".*_GCM_.*");

        HttpConfiguration httpsConf = new HttpConfiguration();
        httpsConf.setSecurePort(httpsPort);
        httpsConf.setSecureScheme("https");
        httpsConf.addCustomizer(new SecureRequestCustomizer());

        ServerConnector httpsConnector = new ServerConnector(server,
                new SslConnectionFactory(sslContextFactory, "http/1.1"),
                new HttpConnectionFactory(httpsConf));
        httpsConnector.setHost("mydomain.com");
        httpsConnector.setPort(httpsPort);
        server.addConnector(httpsConnector);

        HandlerList baseHandlers = new HandlerList();
        server.setHandler(baseHandlers);

        ServletContextHandler context = new ServletContextHandler();
        // context.setVirtualHosts(new String[] {"mydomain.com"});
        context.setContextPath("/");

        baseHandlers.addHandler(context);

        // Add WebSocket
        ServerContainer jsrContainer = WebSocketServerContainerInitializer.configureContext(context);
        jsrContainer.setDefaultMaxSessionIdleTimeout(1000 * 60 * 60 * 24);
        jsrContainer.addEndpoint(RequestServerEndpoint.class);

        Handler handler = new DefaultHandler();
        baseHandlers.addHandler(handler);

        server.setDumpAfterStart(true);
        server.setDumpBeforeStop(true);

        try {
            server.start();
            server.join();
        } catch (Throwable t) {
            t.printStackTrace(System.err);
        }
    }

    public void stop() throws Exception {
        if( server != null ){
            server.stop();
            server = null;
        }
    }
}

此代码使用jetty-all-9.3.1.v20150714-uber.jar作为websocket库。

com.mydomain.desktopclient.resources.ResourceLoader是一个简单的类,用于从应用程序的jar文件中查找和返回文件作为资源。

如果需要,这是RequestServerEndpoint:

package com.mydomain.desktopclient.websockets.server.endpoint;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.logging.Logger;

@ServerEndpoint(value = "/appservices")
public class RequestServerEndpoint {

    private static Logger logger = Logger.getLogger(RequestServerEndpoint.class.getName());

    @OnOpen
    public void onOpen(Session session) {
        logger.info("Connected ... " + session.getId());
    }

    @OnMessage
    public String onMessage(String incommingMessage, Session session) {
        logger.info("Received Message: \n\n" + incommingMessage);
    }

    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
        logger.info(String.format("Session %s closed because of %s", session.getId(), closeReason));
    }
}

0 个答案:

没有答案