Websockets über HTTPS mit spring-boot 1.0.0.RC5 und tomcat 8.0.3

Habe ich ein funktionierendes Beispiel des web socket (ws) nicht-sicheren Implementierung-Anwendung mit spring-boot 1.0.0.RC5 und tomcat 8.0.3.
Nun würde ich gerne wechseln wss-also mit mir selbst signierten Zertifikats, das beladen war von tomcat schon.

Diese Frage hat zwei Teile, einen theoretischen und einen praktischen:

Theoretische => muss ich tomcat lauscht auf zwei ports? also auf http-und https. Der Grund warum ich Frage dies, da ich gelesen habe, dass bei einer web socket-Kommunikation der erste Teil der Verbindung über http und dann gibt es so genannte "upgrade" zu websockets. Ich bin Entsendung Beispiel von meinem test

GET /hello HTTP/1.1
Host: 127.0.0.5:8080
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:28.0) Gecko/20100101 Firefox/28.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en,en-gb;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Sec-WebSocket-Version: 13
Origin: http://localhost:8080
Sec-WebSocket-Key: wIKSOMgaHbEmkaRuEHZ6IA==
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket


HTTP/1.1 101 Switching Protocols
Server: Apache-Coyote/1.1
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Accept: 8trj6dyzlYdDUA3nAuwiM7SijRM=
Date: Mon, 31 Mar 2014 10:29:19 GMT


..,O.do..*i..nM,..\;..I=.
C!.U.~.U....I....-..Xu.T...H...T.E.d
.'
CONNECTED
heart-beat:0,0
version:1.1

.
.....]..M...F...f9..z?...9..{4..{4..5r...4..h/..{4..|W..

Wie diese Kommunikation Aussehen würde, über wss? Wir haben die "upgrade" - Teil so gut, wenn so benötigen wir in diesem Fall http, damit dieses Konstrukt funktioniert.

Praktische => Das problem, das ich konfrontiert ist, dass der Teil des Codes, ist verantwortlich für die Erstellung des stomp-Nachricht funktioniert nicht, d.h. wenn ich die Seite öffnen

https://127.0.0.5:8888/wsTest

firefox erzählte mir
"Diese Verbindung ist nicht vertrauenswürdig" dann erzähle ich firefox "ich verstehe das Risiko" und fügen Sie das Zertifikat als "Sicherheits-Ausnahme". Von diesem Punkt können Sie das Zertifikat gespeichert unter firefox "Server" - Registerkarte.
Alles gut bis jetzt. Jedoch wenn ich auf die wss funktioniert dieses Spiel nicht, wie ich es erwartet habe zu arbeiten. d.h. Diese Funktion ist das erstellen der socket auf der client-Seite.

     function connect() {
            var socket = new WebSocket("wss://127.0.0.5:8888/hello");

            stompClient = Stomp.over(socket);
            stompClient.connect({}, function(frame) {
                setConnected(true);
                console.log('Connected: ' + frame);
                stompClient.subscribe('/topic/greetings', function(greeting){
                    showGreeting(JSON.parse(greeting.body).content);
                });
            });
        } 

wenn ich die Zeile ändern

var socket = new WebSocket("wss://127.0.0.5:8888/hello"); 

auf die http-version, d.h.

var socket = new WebSocket("ws://127.0.0.5:8080/hello"); 

dann funktioniert alles wieder. Das problem scheint zu sein, mit der Linie

stompClient.connect({}, function(frame) {

aber nach diesem Fehler-Hinweis (https://jira.spring.io/browse/SPR-11436) sollte dies die richtige Linie

Habe ich generiert die ceritficate mit dem Befehl:

keytool -genkey -alias tomcat -keyalg RSA  -keystore /home/tito/Projects/syncServer/Server/certificate/sync.keystore

Server-Seite:

@Configuration
public class TomcatEmbeded extends SpringServletContainerInitializer {


    final int http_port = 8080;
    final int https_port = 8888;
    final String keystoreFile = "/home/tito/Projects/syncServer/Server/certificate/sync.keystore";
    final String keystorePass = "changeit";
    final String keystoreType = "JKS";
    final String keystoreProvider = "SUN";
    final String keystoreAlias = "tomcat";
    final String https_scheme = "https";
    final String http_scheme = "http";

    @Bean
    public EmbeddedServletContainerFactory servletContainer() {


        TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory(http_port);

        factory.setTomcatContextCustomizers(
                Arrays.asList (
                        new TomcatContextCustomizer[]{ 
                                tomcatContextCustomizer() 
                                } 
                            )
                        );

        factory.addConnectorCustomizers( new TomcatConnectorCustomizer() {
            @Override
            public void customize(Connector con) {
                    Http11NioProtocol proto = (Http11NioProtocol) con.getProtocolHandler();

                    try {

                        con.setPort(https_port);
                        con.setSecure(true);
                        con.setScheme("https");
                        con.setAttribute("keyAlias", keystoreAlias);
                        con.setAttribute("keystorePass", keystorePass.toString());
                        try {
                            con.setAttribute("keystoreFile", ResourceUtils.getFile(keystoreFile).getAbsolutePath());
                        } catch (FileNotFoundException e) {
                            throw new IllegalStateException("Cannot load keystore", e);
                        }

                        con.setAttribute("clientAuth", "false");
                        con.setAttribute("sslProtocol", "TLS");
                        con.setAttribute("SSLEnabled", true);

                        proto.setSSLEnabled(true);
                        proto.setKeystoreFile(keystoreFile);
                        proto.setKeystorePass(keystorePass);
                        proto.setKeystoreType(keystoreType);
                        proto.setProperty("keystoreProvider", keystoreProvider.toString());
                        proto.setKeyAlias(keystoreAlias);

                    } catch (Exception ex) {
                        throw new IllegalStateException("can't access keystore: [" + "keystore"
                                + "] or truststore: [" + "keystore" + "]", ex);
                    }
                    System.out.println("INIT HTTPS");

                }
            }
        );


        factory.addAdditionalTomcatConnectors(httpConnector());
//     factory.addErrorPages(new ErrorPage(HttpStatus.404, "/notfound.html");
        System.out.println("TOMCAT CUSTOME SETTINGS INITILIZED");

        return factory;
    }


    private Connector httpConnector() {
        Connector connector = new Connector();
        connector.setScheme(this.http_scheme);
        connector.setSecure(true);
        connector.setPort(this.http_port);
        System.out.println("INIT port HTTP");
        return connector;
    }


    @Bean 
    public TomcatContextCustomizer tomcatContextCustomizer() {
        System.out.println("TOMCATCONTEXTCUSTOMIZER INITILIZED");
        return new TomcatContextCustomizer() {

            @Override
            public void customize(Context context) {
                //TODO Auto-generated method stub
                context.addServletContainerInitializer(new WsSci(), null);


            }
        };
    }

hier ist die web-socket-Konfiguration Teil

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/hello");
    }


    @Override
    public void configureClientInboundChannel(ChannelRegistration channelRegistration) {
    }

    @Override
    public void configureClientOutboundChannel(ChannelRegistration channelRegistration) {
    }

    @Override
    public boolean configureMessageConverters(List<MessageConverter> arg0) {

        return true;
    } 

weitere Nachrichten sehen Sie auf der firefox-debug-Konsole

Use of getUserData() or setUserData() is deprecated.  Use WeakMap or element.dataset instead. requestNotifier.js:64
"Opening Web Socket..." stomp.js:130
Firefox can't establish a connection to the server at wss://127.0.0.5:8888/hello. wsTest:18
"Whoops! Lost connection to wss://127.0.0.5:8888/hello" stomp.js:130

hier ist die vollständige version der html-Seite

<!DOCTYPE html>
<html>
<head>
    <title>Hello WebSocket</title>
    <script src="/js/stomp.js"></script>
    <script type="text/javascript">
        var stompClient = null;

        function setConnected(connected) {
            document.getElementById('connect').disabled = connected;
            document.getElementById('disconnect').disabled = !connected;
            document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
            document.getElementById('response').innerHTML = '';
        }

        function connect() {
            var socket = new WebSocket("wss://127.0.0.5:8888/hello");

            stompClient = Stomp.over(socket);
 //          stompClient.connect('tito', 'password', function(frame) {
            stompClient.connect({}, function(frame) {
                setConnected(true);
                console.log('Connected: ' + frame);
                stompClient.subscribe('/topic/greetings', function(greeting){
                    showGreeting(JSON.parse(greeting.body).content);
                });
            });
        }

        function disconnect() {
            stompClient.disconnect();
            setConnected(false);
            console.log("Disconnected");
        }

        function sendName() {
            var name = document.getElementById('name').value;
            stompClient.send("/app/hello", {}, JSON.stringify({ 'name': name }));
        }

        function showGreeting(message) {
            var response = document.getElementById('response');
            var p = document.createElement('p');
            p.style.wordWrap = 'break-word';
            p.appendChild(document.createTextNode(message));
            response.appendChild(p);
        }
    </script>
</head>
<body>
<noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being enabled. Please enable
    Javascript and reload this page!</h2></noscript>
<div>
    <div>
        <button id="connect" onclick="connect();">Connect</button>
        <button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>
    </div>
    <div id="conversationDiv">
        <label>What is your name?</label><input type="text" id="name" />
        <button id="sendName" onclick="sendName();">Send</button>
        <p id="response"></p>
    </div>
</div>
</body>
</html>

die stomp-script-version verwendet wird, ist "//Generated by CoffeeScript 1.6.3"

hier ist, wie das Zertifikat generiert wurde,

$ keytool -genkey -alias tomcat -keyalg RSA  -keystore /home/tito/Projects/syncServer/Server/certificate/sync.keystore
Enter keystore password:  
Re-enter new password: 
What is your first and last name?
  [Unknown]:  TestFirstName
What is the name of your organizational unit?
  [Unknown]:  TestOrganizationalUnitName
What is the name of your organization?
  [Unknown]:  TestOrganization
What is the name of your City or Locality?
  [Unknown]:  TestCity
What is the name of your State or Province?
  [Unknown]:  TestState
What is the two-letter country code for this unit?
  [Unknown]:  BG
Is CN=TestFirstName, OU=TestOrganizationalUnitName, O=TestOrganization, L=TestCity, ST=TestState, C=BG correct?
  [no]:  yes

Enter key password for <tomcat>
        (RETURN if same as keystore password):  

Zusatz: ich habe auch bemerkt, dass web sockets arbeiten, wenn ich rufe

https://127.0.0.5:8888/wsTest  

aber nicht funktioniert, wenn ich rufe

https://localhost:8888/wsTest

aber ich habe noch nicht herausgefunden, warum dies geschieht. Dieses Verhalten ist das gleiche mit chrome und firefox.

  • Sie müssen auf jeden Fall eine HTTPS-connector für Websockets mit SSL, (I. e. Ihre "wss://*" client"). Es ist möglich, es funktioniert nicht, weil das problem mit dem Zertifikat (Sie nahmen das Risiko für die direkte browser-verbindungen, aber vielleicht haben Sie etwas zu tun, ähnlich wie bei den JavaScript-client, wie eine Flagge auf it). Ich weiß wirklich nicht, die client Seite ist es sehr gut.
  • Hallo Dave, danke für die schnelle Antwort, ich weiß, dass ich brauche den https-Anschluss für wss zu arbeiten, jedoch war meine Frage, benötige ich die http auch gleichzeitig mit der https-connector. Was bezieht sich auf die client-Seite, das ist die standard-Seite ausgeführt, von der web-browser stammt aus der Feder Führer dh github.com/spring-guides/gs-messaging-stomp-websocket/blob/.... Ich habe nur geändert, das Teil, das der Kunde für mozilla d.h. der Erstellung der web-sockel : var socket = new WebSocket("wss://E-Mails 127.0.0.5:8888/hello");
  • und entfernt den sockjs lib, da ich nicht jede fallback, d.h. entfernt <script src="sockjs-0.3.4.js"></script>
  • Nein, Sie brauchen nicht HTTP als auch. Sehen Sie irgendwelche Fehler oder Meldungen in der browser-Konsole (developer tools)?
  • ja ich weiß , ich habe diese Nachrichten an das Ende der problem-Beschreibung
  • Können Sie sehen, die security exception " auf den richtigen port und host in der Firefox-config?
  • Dave, ich bin nicht sicher, ob ich am folgenden kannst du die bitte umformulieren, dass Letzte Satz. Meinst du ich muss in der firefox-config also "about:config" und suchen Sie dort etwas ? Oder meinst du, wenn der port korrekt ist, d.h. 8888 wenn ja, dann ja, ist es.
  • Wie wäre es einfach versucht es in den Chrome?
  • In firefox solltest du lieber gehen Sie zu Optionen - erweitert - Verschlüsselung, dann auf "Zertifikate Anzeigen" - Taste und schauen auf den Servern. Stellen Sie sicher, dass der hostname und port ein, den Sie brauchen gibt es.
  • Hallo Dave, danke für die Unterstützung. Es funktioniert jetzt. Ich bin nicht sicher, warum, aber hier ist was ich getan habe. Ich erzeugte ein neues Zertifikat mit dem gleichen Befehl, den ich verwendet, bevor. Dann sah ich, dass mein letzter Zertifikat hatte in allen Bereich nur eine Charakter-Werte. Vielleicht war das problem von Anfang an. Wenn ich einige wirklich sinnvolle Daten in das Zertifikat arbeitete er für gekauft, chrome und firefox.
  • Hallo @Tito, ich die Umsetzung das gleiche Szenario wie du oben erwähnt, aber noch stehe ich vor ein Problem, könnten Sie mir bitte helfen mit diesem?

InformationsquelleAutor Tito | 2014-03-31
Schreibe einen Kommentar