Showing
9 changed files
with
54 additions
and
286 deletions
... | ... | @@ -126,7 +126,7 @@ |
126 | 126 | </dependency> |
127 | 127 | <dependency> |
128 | 128 | <groupId>org.springframework.boot</groupId> |
129 | - <artifactId>spring-boot-starter-webflux</artifactId> | |
129 | + <artifactId>spring-boot-starter-websocket</artifactId> | |
130 | 130 | </dependency> |
131 | 131 | <dependency> |
132 | 132 | <groupId>io.jsonwebtoken</groupId> | ... | ... |
application/src/main/java/org/thingsboard/server/config/ThingsboardWebFluxSecurityConfig.java
deleted
100644 → 0
1 | -/** | |
2 | - * Copyright © 2016-2019 The Thingsboard Authors | |
3 | - * | |
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | - * you may not use this file except in compliance with the License. | |
6 | - * You may obtain a copy of the License at | |
7 | - * | |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | - * | |
10 | - * Unless required by applicable law or agreed to in writing, software | |
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | - * See the License for the specific language governing permissions and | |
14 | - * limitations under the License. | |
15 | - */ | |
16 | -package org.thingsboard.server.config; | |
17 | - | |
18 | -import org.springframework.beans.factory.annotation.Autowired; | |
19 | -import org.springframework.context.annotation.Bean; | |
20 | -import org.springframework.security.authentication.AuthenticationManager; | |
21 | -import org.springframework.security.authentication.ReactiveAuthenticationManager; | |
22 | -import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity; | |
23 | -import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; | |
24 | -import org.springframework.security.config.web.server.SecurityWebFiltersOrder; | |
25 | -import org.springframework.security.config.web.server.ServerHttpSecurity; | |
26 | -import org.springframework.security.web.server.SecurityWebFilterChain; | |
27 | -import org.springframework.security.web.server.context.ServerSecurityContextRepository; | |
28 | - | |
29 | -//@EnableWebFluxSecurity | |
30 | -//@EnableReactiveMethodSecurity | |
31 | -public class ThingsboardWebFluxSecurityConfig { | |
32 | - | |
33 | - private static final String WS_TOKEN_BASED_AUTH_ENTRY_POINT = "/api/ws/**"; | |
34 | - | |
35 | - @Autowired | |
36 | - private ReactiveAuthenticationManager webfluxAuthenticationManager; | |
37 | - | |
38 | - @Autowired | |
39 | - private ServerSecurityContextRepository jwtTokenSecurityContextRepository; | |
40 | - | |
41 | - @Bean | |
42 | - public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { | |
43 | - return http | |
44 | - .cors() | |
45 | - .and() | |
46 | - .csrf().disable() | |
47 | - .formLogin().disable() | |
48 | - .httpBasic().disable() | |
49 | - .exceptionHandling() | |
50 | - .and() | |
51 | - .authenticationManager(webfluxAuthenticationManager) | |
52 | - .securityContextRepository(jwtTokenSecurityContextRepository) | |
53 | - .authorizeExchange() | |
54 | - .pathMatchers(WS_TOKEN_BASED_AUTH_ENTRY_POINT) | |
55 | - .authenticated() | |
56 | - .and() | |
57 | - .build(); | |
58 | - } | |
59 | - | |
60 | -} |
... | ... | @@ -21,63 +21,44 @@ import org.springframework.http.HttpStatus; |
21 | 21 | import org.springframework.http.server.ServerHttpRequest; |
22 | 22 | import org.springframework.http.server.ServerHttpResponse; |
23 | 23 | import org.springframework.security.core.Authentication; |
24 | -import org.springframework.security.core.context.SecurityContext; | |
25 | 24 | import org.springframework.security.core.context.SecurityContextHolder; |
26 | -import org.springframework.security.web.server.context.WebSessionServerSecurityContextRepository; | |
27 | -import org.springframework.web.reactive.HandlerMapping; | |
28 | -import org.springframework.web.reactive.HandlerResult; | |
29 | -import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping; | |
30 | -import org.springframework.web.reactive.socket.WebSocketHandler; | |
31 | -import org.springframework.web.reactive.socket.server.support.HandshakeWebSocketService; | |
32 | -import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter; | |
33 | -import org.springframework.web.server.ServerWebExchange; | |
25 | +import org.springframework.web.socket.WebSocketHandler; | |
26 | +import org.springframework.web.socket.config.annotation.EnableWebSocket; | |
27 | +import org.springframework.web.socket.config.annotation.WebSocketConfigurer; | |
28 | +import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; | |
29 | +import org.springframework.web.socket.server.HandshakeInterceptor; | |
30 | +import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean; | |
31 | +import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor; | |
34 | 32 | import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; |
35 | 33 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
36 | 34 | import org.thingsboard.server.controller.plugin.TbWebSocketHandler; |
37 | 35 | import org.thingsboard.server.service.security.model.SecurityUser; |
38 | -import reactor.core.publisher.Mono; | |
39 | 36 | |
40 | -import java.util.HashMap; | |
41 | 37 | import java.util.Map; |
42 | 38 | |
43 | 39 | @Configuration |
44 | -public class WebSocketConfiguration { | |
40 | +@EnableWebSocket | |
41 | +public class WebSocketConfiguration implements WebSocketConfigurer { | |
45 | 42 | |
46 | 43 | public static final String WS_PLUGIN_PREFIX = "/api/ws/plugins/"; |
47 | 44 | private static final String WS_PLUGIN_MAPPING = WS_PLUGIN_PREFIX + "**"; |
48 | 45 | |
49 | -/* @Bean | |
46 | + @Bean | |
50 | 47 | public ServletServerContainerFactoryBean createWebSocketContainer() { |
51 | 48 | ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean(); |
52 | 49 | container.setMaxTextMessageBufferSize(32768); |
53 | 50 | container.setMaxBinaryMessageBufferSize(32768); |
54 | 51 | return container; |
55 | - }*/ | |
56 | - | |
57 | - @Bean | |
58 | - public HandlerMapping handlerMapping() { | |
59 | - Map<String, WebSocketHandler> map = new HashMap<>(); | |
60 | - map.put(WS_PLUGIN_MAPPING, wsHandler()); | |
61 | - | |
62 | - SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); | |
63 | - mapping.setUrlMap(map); | |
64 | - mapping.setOrder(-1); // before annotated controllers | |
65 | - return mapping; | |
66 | 52 | } |
67 | 53 | |
68 | - @Bean | |
69 | - public WebSocketHandlerAdapter handlerAdapter() { | |
70 | - return new WebSocketHandlerAdapter(); | |
71 | - } | |
72 | - | |
73 | -/* @Override | |
54 | + @Override | |
74 | 55 | public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { |
75 | 56 | registry.addHandler(wsHandler(), WS_PLUGIN_MAPPING).setAllowedOrigins("*") |
76 | 57 | .addInterceptors(new HttpSessionHandshakeInterceptor(), new HandshakeInterceptor() { |
77 | 58 | |
78 | 59 | @Override |
79 | 60 | public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, |
80 | - Map<String, Object> attributes) throws Exception { | |
61 | + Map<String, Object> attributes) throws Exception { | |
81 | 62 | SecurityUser user = null; |
82 | 63 | try { |
83 | 64 | user = getCurrentUser(); |
... | ... | @@ -92,23 +73,23 @@ public class WebSocketConfiguration { |
92 | 73 | |
93 | 74 | @Override |
94 | 75 | public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, |
95 | - Exception exception) { | |
76 | + Exception exception) { | |
96 | 77 | //Do nothing |
97 | 78 | } |
98 | 79 | }); |
99 | - }*/ | |
80 | + } | |
100 | 81 | |
101 | 82 | @Bean |
102 | 83 | public WebSocketHandler wsHandler() { |
103 | 84 | return new TbWebSocketHandler(); |
104 | 85 | } |
105 | 86 | |
106 | -/* protected SecurityUser getCurrentUser() throws ThingsboardException { | |
87 | + protected SecurityUser getCurrentUser() throws ThingsboardException { | |
107 | 88 | Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); |
108 | 89 | if (authentication != null && authentication.getPrincipal() instanceof SecurityUser) { |
109 | 90 | return (SecurityUser) authentication.getPrincipal(); |
110 | 91 | } else { |
111 | 92 | throw new ThingsboardException("You aren't authorized to perform this operation!", ThingsboardErrorCode.AUTHENTICATION); |
112 | 93 | } |
113 | - }*/ | |
94 | + } | |
114 | 95 | } | ... | ... |
... | ... | @@ -16,51 +16,48 @@ |
16 | 16 | package org.thingsboard.server.controller.plugin; |
17 | 17 | |
18 | 18 | import lombok.extern.slf4j.Slf4j; |
19 | +import org.springframework.beans.factory.BeanCreationNotAllowedException; | |
20 | +import org.springframework.beans.factory.annotation.Autowired; | |
21 | +import org.springframework.beans.factory.annotation.Value; | |
22 | +import org.springframework.security.core.Authentication; | |
19 | 23 | import org.springframework.stereotype.Service; |
20 | -import org.springframework.web.reactive.socket.CloseStatus; | |
21 | -import org.springframework.web.reactive.socket.WebSocketHandler; | |
22 | -import org.springframework.web.reactive.socket.WebSocketSession; | |
24 | +import org.springframework.util.StringUtils; | |
25 | +import org.springframework.web.socket.CloseStatus; | |
26 | +import org.springframework.web.socket.TextMessage; | |
27 | +import org.springframework.web.socket.WebSocketSession; | |
28 | +import org.springframework.web.socket.adapter.NativeWebSocketSession; | |
29 | +import org.springframework.web.socket.handler.TextWebSocketHandler; | |
30 | +import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; | |
31 | +import org.thingsboard.server.common.data.id.CustomerId; | |
32 | +import org.thingsboard.server.common.data.id.TenantId; | |
33 | +import org.thingsboard.server.common.data.id.UserId; | |
34 | +import org.thingsboard.server.common.msg.tools.TbRateLimits; | |
35 | +import org.thingsboard.server.config.WebSocketConfiguration; | |
23 | 36 | import org.thingsboard.server.service.security.model.SecurityUser; |
37 | +import org.thingsboard.server.service.security.model.UserPrincipal; | |
38 | +import org.thingsboard.server.service.telemetry.SessionEvent; | |
24 | 39 | import org.thingsboard.server.service.telemetry.TelemetryWebSocketMsgEndpoint; |
40 | +import org.thingsboard.server.service.telemetry.TelemetryWebSocketService; | |
25 | 41 | import org.thingsboard.server.service.telemetry.TelemetryWebSocketSessionRef; |
26 | -import reactor.core.publisher.Mono; | |
27 | 42 | |
43 | +import javax.websocket.*; | |
28 | 44 | import java.io.IOException; |
29 | -import java.security.Principal; | |
45 | +import java.net.URI; | |
46 | +import java.security.InvalidParameterException; | |
47 | +import java.util.Queue; | |
48 | +import java.util.Set; | |
49 | +import java.util.UUID; | |
50 | +import java.util.concurrent.ConcurrentHashMap; | |
51 | +import java.util.concurrent.ConcurrentMap; | |
52 | +import java.util.concurrent.LinkedBlockingQueue; | |
30 | 53 | |
31 | 54 | @Service |
32 | 55 | @Slf4j |
33 | -public class TbWebSocketHandler implements WebSocketHandler, TelemetryWebSocketMsgEndpoint { | |
56 | +public class TbWebSocketHandler extends TextWebSocketHandler implements TelemetryWebSocketMsgEndpoint { | |
34 | 57 | |
35 | - @Override | |
36 | - public Mono<Void> handle(WebSocketSession session) { | |
37 | - return session.receive() | |
38 | - .doOnNext(message -> { | |
39 | - Principal principal = session.getHandshakeInfo().getPrincipal().block(); | |
40 | - if (principal instanceof SecurityUser) { | |
41 | - SecurityUser currentUser = (SecurityUser) principal; | |
42 | - log.info("[{}][{}] Processing {}", currentUser.getTenantId(), session.getId(), message.getPayloadAsText()); | |
43 | - } else { | |
44 | - log.info("[{}] Principal {}", session.getId(), principal); | |
45 | - log.info("[{}] Processing {}", session.getId(), message.getPayloadAsText()); | |
46 | - } | |
47 | - }) | |
48 | - .then(); | |
49 | - } | |
50 | - | |
51 | - @Override | |
52 | - public void send(TelemetryWebSocketSessionRef sessionRef, int subscriptionId, String msg) throws IOException { | |
58 | + private static final ConcurrentMap<String, SessionMetaData> internalSessionMap = new ConcurrentHashMap<>(); | |
59 | + private static final ConcurrentMap<String, String> externalSessionMap = new ConcurrentHashMap<>(); | |
53 | 60 | |
54 | - } | |
55 | - | |
56 | - @Override | |
57 | - public void close(TelemetryWebSocketSessionRef sessionRef, CloseStatus withReason) throws IOException { | |
58 | - | |
59 | - } | |
60 | - | |
61 | -// private static final ConcurrentMap<String, SessionMetaData> internalSessionMap = new ConcurrentHashMap<>(); | |
62 | -// private static final ConcurrentMap<String, String> externalSessionMap = new ConcurrentHashMap<>(); | |
63 | -/* | |
64 | 61 | @Autowired |
65 | 62 | private TelemetryWebSocketService webSocketService; |
66 | 63 | |
... | ... | @@ -106,22 +103,6 @@ public class TbWebSocketHandler implements WebSocketHandler, TelemetryWebSocketM |
106 | 103 | } |
107 | 104 | |
108 | 105 | @Override |
109 | - public Mono<Void> handle(WebSocketSession session) { | |
110 | - return session.receive() | |
111 | - .doOnNext(message -> { | |
112 | - Principal principal = session.getHandshakeInfo().getPrincipal().block(); | |
113 | - if (principal instanceof SecurityUser) { | |
114 | - SecurityUser currentUser = (SecurityUser) principal; | |
115 | - log.info("[{}][{}] Processing {}", currentUser.getTenantId(), session.getId(), message.getPayloadAsText()); | |
116 | - } else { | |
117 | - log.info("[{}] Principal {}", session.getId(), principal); | |
118 | - log.info("[{}] Processing {}", session.getId(), message.getPayloadAsText()); | |
119 | - } | |
120 | - }) | |
121 | - .then(); | |
122 | - } | |
123 | - | |
124 | - @Override | |
125 | 106 | public void afterConnectionEstablished(WebSocketSession session) throws Exception { |
126 | 107 | super.afterConnectionEstablished(session); |
127 | 108 | try { |
... | ... | @@ -410,5 +391,5 @@ public class TbWebSocketHandler implements WebSocketHandler, TelemetryWebSocketM |
410 | 391 | } |
411 | 392 | } |
412 | 393 | } |
413 | - */ | |
414 | -} | |
394 | + | |
395 | +} | |
\ No newline at end of file | ... | ... |
application/src/main/java/org/thingsboard/server/service/security/auth/webflux/WebfluxAuthenticationManager.java
deleted
100644 → 0
1 | -/** | |
2 | - * Copyright © 2016-2019 The Thingsboard Authors | |
3 | - * | |
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | - * you may not use this file except in compliance with the License. | |
6 | - * You may obtain a copy of the License at | |
7 | - * | |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | - * | |
10 | - * Unless required by applicable law or agreed to in writing, software | |
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | - * See the License for the specific language governing permissions and | |
14 | - * limitations under the License. | |
15 | - */ | |
16 | -package org.thingsboard.server.service.security.auth.webflux; | |
17 | - | |
18 | -import org.springframework.beans.factory.annotation.Autowired; | |
19 | -import org.springframework.security.authentication.ReactiveAuthenticationManager; | |
20 | -import org.springframework.security.core.Authentication; | |
21 | -import org.springframework.stereotype.Component; | |
22 | -import org.thingsboard.server.service.security.auth.JwtAuthenticationToken; | |
23 | -import org.thingsboard.server.service.security.model.SecurityUser; | |
24 | -import org.thingsboard.server.service.security.model.token.JwtTokenFactory; | |
25 | -import org.thingsboard.server.service.security.model.token.RawAccessJwtToken; | |
26 | -import reactor.core.publisher.Mono; | |
27 | - | |
28 | -@Component | |
29 | -public class WebfluxAuthenticationManager implements ReactiveAuthenticationManager { | |
30 | - | |
31 | - @Autowired | |
32 | - private JwtTokenFactory tokenFactory; | |
33 | - | |
34 | - @Override | |
35 | - public Mono<Authentication> authenticate(Authentication authentication) { | |
36 | - try { | |
37 | - if (authentication.getCredentials() != null && authentication.getCredentials() instanceof RawAccessJwtToken) { | |
38 | - RawAccessJwtToken rawAccessToken = (RawAccessJwtToken) authentication.getCredentials(); | |
39 | - SecurityUser securityUser = tokenFactory.parseAccessJwtToken(rawAccessToken); | |
40 | - JwtAuthenticationToken auth = new JwtAuthenticationToken(securityUser); | |
41 | - return Mono.just(auth); | |
42 | - } | |
43 | - return Mono.empty(); | |
44 | - } catch (Exception e) { | |
45 | - return Mono.error(e); | |
46 | - } | |
47 | - } | |
48 | -} |
application/src/main/java/org/thingsboard/server/service/security/auth/webflux/jwt/JwtTokenSecurityContextRepository.java
deleted
100644 → 0
1 | -/** | |
2 | - * Copyright © 2016-2019 The Thingsboard Authors | |
3 | - * | |
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | - * you may not use this file except in compliance with the License. | |
6 | - * You may obtain a copy of the License at | |
7 | - * | |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | - * | |
10 | - * Unless required by applicable law or agreed to in writing, software | |
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | - * See the License for the specific language governing permissions and | |
14 | - * limitations under the License. | |
15 | - */ | |
16 | -package org.thingsboard.server.service.security.auth.webflux.jwt; | |
17 | - | |
18 | -import org.springframework.beans.factory.annotation.Autowired; | |
19 | -import org.springframework.beans.factory.annotation.Qualifier; | |
20 | -import org.springframework.http.server.reactive.ServerHttpRequest; | |
21 | -import org.springframework.security.authentication.AuthenticationManager; | |
22 | -import org.springframework.security.authentication.ReactiveAuthenticationManager; | |
23 | -import org.springframework.security.core.Authentication; | |
24 | -import org.springframework.security.core.context.SecurityContext; | |
25 | -import org.springframework.security.core.context.SecurityContextImpl; | |
26 | -import org.springframework.security.web.server.context.ServerSecurityContextRepository; | |
27 | -import org.springframework.security.web.server.context.WebSessionServerSecurityContextRepository; | |
28 | -import org.springframework.stereotype.Component; | |
29 | -import org.springframework.util.StringUtils; | |
30 | -import org.springframework.web.server.ServerWebExchange; | |
31 | -import org.thingsboard.server.config.ThingsboardSecurityConfiguration; | |
32 | -import org.thingsboard.server.service.security.auth.JwtAuthenticationToken; | |
33 | -import org.thingsboard.server.service.security.auth.jwt.extractor.TokenExtractor; | |
34 | -import org.thingsboard.server.service.security.model.token.RawAccessJwtToken; | |
35 | -import reactor.core.publisher.Mono; | |
36 | - | |
37 | -import java.util.List; | |
38 | - | |
39 | -@Component | |
40 | -public class JwtTokenSecurityContextRepository implements ServerSecurityContextRepository { | |
41 | - | |
42 | - public static final String DEFAULT_SPRING_SECURITY_CONTEXT_ATTR_NAME = "SPRING_SECURITY_CONTEXT"; | |
43 | - | |
44 | - @Autowired | |
45 | - private ReactiveAuthenticationManager webfluxAuthenticationManager; | |
46 | - | |
47 | - @Override | |
48 | - public Mono<Void> save(ServerWebExchange exchange, SecurityContext context) { | |
49 | - return exchange.getSession() | |
50 | - .doOnNext(session -> { | |
51 | - if (context == null) { | |
52 | - session.getAttributes().remove(WebSessionServerSecurityContextRepository.DEFAULT_SPRING_SECURITY_CONTEXT_ATTR_NAME); | |
53 | - } else { | |
54 | - session.getAttributes().put(WebSessionServerSecurityContextRepository.DEFAULT_SPRING_SECURITY_CONTEXT_ATTR_NAME, context); | |
55 | - } | |
56 | - }) | |
57 | - .flatMap(session -> session.changeSessionId()); | |
58 | - } | |
59 | - | |
60 | - @Override | |
61 | - public Mono<SecurityContext> load(ServerWebExchange exchange) { | |
62 | - ServerHttpRequest request = exchange.getRequest(); | |
63 | - String token = extractTokenFromQuery(request); | |
64 | - if (!StringUtils.isEmpty(token)) { | |
65 | - RawAccessJwtToken rawToken = new RawAccessJwtToken(token); | |
66 | - Authentication auth = new JwtAuthenticationToken(rawToken); | |
67 | - return this.webfluxAuthenticationManager.authenticate(auth).map((authentication) -> { | |
68 | - return new SecurityContextImpl(authentication); | |
69 | - }); | |
70 | - } else { | |
71 | - return Mono.empty(); | |
72 | - } | |
73 | - } | |
74 | - | |
75 | - private String extractTokenFromQuery(ServerHttpRequest request) { | |
76 | - String token = null; | |
77 | - if (request.getQueryParams() != null) { | |
78 | - List<String> tokenParamValue = request.getQueryParams().get(ThingsboardSecurityConfiguration.JWT_TOKEN_QUERY_PARAM); | |
79 | - if (tokenParamValue != null && !tokenParamValue.isEmpty()) { | |
80 | - token = tokenParamValue.get(0); | |
81 | - } | |
82 | - } | |
83 | - return token; | |
84 | - } | |
85 | - | |
86 | -} |
... | ... | @@ -26,7 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired; |
26 | 26 | import org.springframework.beans.factory.annotation.Value; |
27 | 27 | import org.springframework.stereotype.Service; |
28 | 28 | import org.springframework.util.StringUtils; |
29 | -import org.springframework.web.reactive.socket.CloseStatus; | |
29 | +import org.springframework.web.socket.CloseStatus; | |
30 | 30 | import org.thingsboard.server.common.data.DataConstants; |
31 | 31 | import org.thingsboard.server.common.data.id.CustomerId; |
32 | 32 | import org.thingsboard.server.common.data.id.EntityId; | ... | ... |
... | ... | @@ -50,7 +50,7 @@ |
50 | 50 | <commons-validator.version>1.5.0</commons-validator.version> |
51 | 51 | <commons-io.version>2.5</commons-io.version> |
52 | 52 | <commons-csv.version>1.4</commons-csv.version> |
53 | - <jackson.version>2.9.0</jackson.version> | |
53 | + <jackson.version>2.9.7</jackson.version> | |
54 | 54 | <json-schema-validator.version>2.2.6</json-schema-validator.version> |
55 | 55 | <scala.version>2.11</scala.version> |
56 | 56 | <akka.version>2.4.2</akka.version> |
... | ... | @@ -424,7 +424,7 @@ |
424 | 424 | </dependency> |
425 | 425 | <dependency> |
426 | 426 | <groupId>org.springframework.boot</groupId> |
427 | - <artifactId>spring-boot-starter-webflux</artifactId> | |
427 | + <artifactId>spring-boot-starter-websocket</artifactId> | |
428 | 428 | <version>${spring-boot.version}</version> |
429 | 429 | </dependency> |
430 | 430 | <dependency> | ... | ... |