原文 http://www.tuicool.com/articles/goto?id=JR3mmy
50th tip on this blog, yaay!
Tech Tip #49explained how to secure WebSockets using username/password and Servlet Security mechanisms. This Tech Tip will explain how to secure WebSockets using HTTPS/TLS on WildFly.
Lets get started!
-
Create a new keystore:
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:
Used “websocket” as the convenience password.
- Download WildFly 8.1 , unzip, and copy “websocket.keystore” file in
standalone/configuration
directory. - Start WildFly as
./bin/standalone.sh
- Connect to it using jboss-cli as:
./bin/jboss-cli.sh -c
-
Add a new security realm as:
[standalone@localhost:9990 /] /core-service=management/security-realm=WebSocketRealm:add() {"outcome" => "success"}
And configure it:
[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" } }
- Add a new HTTPS listener as:
[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"} }
- A simple sample to show TLS-based security for WebSocket is available at github.com/javaee-samples/javaee7-samples/tree/master/websocket/endpoint-wss
. Clone the workspace and change directory to “websocket/endpoint-wss”. The sample’s deployment descriptor has:
<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>
This ensures that any request coming to this application will be auto-directed to an HTTPS URL.
- Deploy the sample by giving the command:
mvn wildfly:deploy
Now accessing http://localhost:8080/endpoint-wss redirects to https://localhost:8080/endpoint-wss . The browsers may complain about self-signed certificate. For example, Chrome shows the following warning:
And Safari shows the following warning:
In either case, click on “Proceed to localhost” or “Continue” to proceed further. And then a secure WebSocket connection is established.
Another relevant point to understand is that a non-secure WebSocket connection cannot be made from an https-protected page. For example the following code in our sample:
new WebSocket("ws://localhost:8080/endpoint-wss/websocket");
will throw the following exception in Chrome Developer Tools:
[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.
Enjoy!