Веб-сокеты на веб-сайте загрузки Spring, размещенном в Azure, возвращают ошибку 503/403

Я создал веб-приложение на Spring Boot, используя Spring Security с аутентификацией Azure AD и веб-сокетами для связи с клиентами. Локально это работает отлично, но когда я развертываю его как веб-приложение Azure, подключение через веб-сокет завершается с ошибкой 503 и 403.

Я пробовал искать ответы здесь и в Google. Некоторые ответы указывают на параметр приложения, в котором вы можете переключать поддержку веб-сокетов в веб-приложении в Azure, но этого параметра больше нет. Многим решениям, которые я нашел, около 5 лет, и они не очень актуальны для моей ситуации.

Я поделюсь некоторым кодом, но он довольно простой и в основном взят из онлайн-руководств от Microsoft и Spring.

Jacascript, который подключается к конечной точке веб-сокета:

stompClient = Stomp.over(socket);
stompClient.connect({}, onConnected, onError);  

Моя конфигурация веб-сокета:

import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer  {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();

    }

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

Конфигурация веб-безопасности:

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .oauth2Login()
            .userInfoEndpoint()
            .oidcUserService(oidcUserService);
        http.headers().frameOptions().disable();
    }
}

пом.xml

<project xmlns = "http://maven.apache.org/POM/4.0.0"
    xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.groupId</groupId>
    <artifactId>artifactId</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Name</name>
    <description>This is a description</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>com.microsoft.azure</groupId>
            <artifactId>azure-active-directory-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-oauth2-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-oauth2-jose</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>com.microsoft.azure</groupId>
                <artifactId>azure-webapp-maven-plugin</artifactId>
                <version>1.5.4</version>
                <configuration>
                    <deploymentType>jar</deploymentType>

                    <!-- configure app to run on port 80, required by App Service -->
                    <appSettings>
                        <property>
                            <name>JAVA_OPTS</name>
                            <value>-Dserver.port=80</value>
                        </property>
                    </appSettings>

                    <!-- Web App information -->
                    <resourceGroup>myResourceGroup</resourceGroup>
                    <appName>myAppName</appName>
                    <region>myRegion</region>
                    <pricingTier>S1</pricingTier>
                    <!-- Java Runtime Stack for Web App on Linux -->
                    <linuxRuntime>jre8</linuxRuntime>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.microsoft.azure</groupId>
                <artifactId>azure-spring-boot-bom</artifactId>
                <version>2.1.2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

Я ожидаю, что веб-сокет будет подключаться так же, как и локально, но я получаю ответ на сообщение об ошибке 503:

Content-Length: 260
Content-Type: text/html
ETag: "5ce7bd82-104"
Server: nginx
Date: Fri, 31 May 2019 07:59:58 GMT

Вслед за этим:

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: application/json;charset=UTF-8
Expires: 0
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Date: Fri, 31 May 2019 07:59:59 GMT

Редактировать: Если я перейду к запрошенному URL-адресу напрямую, я получаю сообщение об ошибке Can "Upgrade" only to "WebSocket".

Редактировать2: Если я отслеживаю журналы своего веб-приложения в клиенте Azure, появляется это сообщение:

0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 975], outboundChannel[pool
 size = 0, active threads = 0, queued tasks = 0, completed tasks = 325], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 1, completed tasks = 53124]```
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
3
0
821
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

    az webapp config set --web-sockets-enabled true --name <sitename> --resource-group <resourcegroupname>

Спасибо, мне, очевидно, нужно было включить это, но это не исправило. Он по-прежнему возвращает 503.

jared 03.06.2019 08:27
Ответ принят как подходящий

Пересматриваю через пару месяцев. Мы разместили приложение в другом сервисе и попытались снова развернуть его в Azure просто так, и веб-сокеты сработали. Я не вносил никаких изменений в приложение или в Azure.

Другие вопросы по теме