Статьи

Защита WebSocket с использованием wss и HTTPS / TLS

50-й совет в этом блоге, да!

Технический совет № 49 объяснил, как защитить WebSockets с помощью имени пользователя / пароля и механизмов безопасности Servlet. Этот технический совет объяснит, как защитить WebSockets с использованием HTTPS / TLS на WildFly.

Давайте начнем!

  1. Создайте новое хранилище ключей:
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    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 каталог standalone/configuration .
  3. Запустите WildFly как:
    1
    ./bin/standalone.sh
  4. Подключитесь к нему, используя jboss-cli как:
    1
    ./bin/jboss-cli.sh -c
  5. Добавьте новую область безопасности как:
    1
    2
    [standalone@localhost:9990 /] /core-service=management/security-realm=WebSocketRealm:add()
    {"outcome" => "success"}

    И настроить это:

    1
    2
    3
    4
    5
    6
    7
    8
    [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 как:
    1
    2
    3
    4
    5
    [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. Простой пример демонстрации безопасности на основе TLS для WebSocket доступен по адресу github.com/javaee-samples/javaee7-samples/tree/master/websocket/endpoint-wss . Клонируйте рабочую область и измените каталог на «websocket / endpoint-wss». Дескриптор развертывания образца имеет:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <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>

    Это гарантирует, что любой запрос, поступающий в это приложение, будет автоматически перенаправлен на URL-адрес HTTPS.

  8. Разверните образец, дав команду:
    1
    mvn wildfly:deploy

Теперь доступ к http: // localhost: 8080 / endpoint-wss перенаправляет на https: // localhost: 8080 / endpoint-wss . Браузеры могут пожаловаться на самозаверяющий сертификат. Например, Chrome отображает следующее предупреждение:

techtip50-сертификат-хром

И Safari показывает следующее предупреждение:

techtip50-сертификат

В любом случае нажмите «Перейти к локальному хосту» или «Продолжить», чтобы продолжить. И тогда устанавливается безопасное соединение WebSocket.

Другим важным моментом, который необходимо понять, является то, что незащищенное соединение WebSocket не может быть установлено со страницы, защищенной https. Например, следующий код в нашем примере:

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

вызовет следующее исключение в Chrome Developer Tools:

1
2
[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.

Наслаждайтесь!

Ссылка: Защита WebSocket с использованием wss и HTTPS / TLS от нашего партнера по JCG Аруна Гупта из блога Miles to go 2.0… .