From f7ed4ffa36f2c1d19c25cc10ce05e7a0be7afb70 Mon Sep 17 00:00:00 2001 From: walker Date: Tue, 13 Jun 2023 18:40:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0websocket=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ats/message/OccTcpClientConnection.java | 2 +- .../SpringSecurityConfiguration.java | 7 ++ .../configuration/WebSocketConfig.java | 86 +++++++++++++++++++ .../joylink/xiannccda/ws/TestController.java | 20 +++++ 4 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 src/main/java/club/joylink/xiannccda/configuration/WebSocketConfig.java create mode 100644 src/main/java/club/joylink/xiannccda/ws/TestController.java diff --git a/src/main/java/club/joylink/xiannccda/ats/message/OccTcpClientConnection.java b/src/main/java/club/joylink/xiannccda/ats/message/OccTcpClientConnection.java index fd96de8..0fc916b 100644 --- a/src/main/java/club/joylink/xiannccda/ats/message/OccTcpClientConnection.java +++ b/src/main/java/club/joylink/xiannccda/ats/message/OccTcpClientConnection.java @@ -78,7 +78,7 @@ public class OccTcpClientConnection { }); channelFuture.channel().closeFuture().addListener(listener -> { if (listener.isSuccess()) { - log.info("与服务断连,尝试重连: {}", this.hostPortInfo()); +// log.warn("与服务断连,尝试重连: {}", this.hostPortInfo()); this.connected = false; this.channel = null; Thread.sleep(3000); diff --git a/src/main/java/club/joylink/xiannccda/configuration/SpringSecurityConfiguration.java b/src/main/java/club/joylink/xiannccda/configuration/SpringSecurityConfiguration.java index decd903..4519b17 100644 --- a/src/main/java/club/joylink/xiannccda/configuration/SpringSecurityConfiguration.java +++ b/src/main/java/club/joylink/xiannccda/configuration/SpringSecurityConfiguration.java @@ -26,6 +26,7 @@ import org.springframework.security.oauth2.jwt.JwtEncoder; import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; import org.springframework.security.oauth2.jwt.NimbusJwtEncoder; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider; import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint; import org.springframework.security.oauth2.server.resource.web.access.BearerTokenAccessDeniedHandler; @@ -57,6 +58,7 @@ public class SpringSecurityConfiguration { static { AuthWhiteList.add(AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/api/user/register")); AuthWhiteList.add(AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/api/user/login")); + AuthWhiteList.add(AntPathRequestMatcher.antMatcher("/ws-default")); AuthWhiteList.add(AntPathRequestMatcher.antMatcher("/swagger-ui/**")); AuthWhiteList.add(AntPathRequestMatcher.antMatcher("/api-docs/**")); AuthWhiteList.add(AntPathRequestMatcher.antMatcher("/swagger-ui.html")); @@ -94,6 +96,11 @@ public class SpringSecurityConfiguration { return http.build(); } + @Bean + public JwtAuthenticationProvider jwtAuthenticationProvider() { + return new JwtAuthenticationProvider(this.jwtDecoder()); + } + @Bean public JwtAuthenticationConverter jwtAuthenticationConverter() { JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter(); diff --git a/src/main/java/club/joylink/xiannccda/configuration/WebSocketConfig.java b/src/main/java/club/joylink/xiannccda/configuration/WebSocketConfig.java new file mode 100644 index 0000000..6a20386 --- /dev/null +++ b/src/main/java/club/joylink/xiannccda/configuration/WebSocketConfig.java @@ -0,0 +1,86 @@ +package club.joylink.xiannccda.configuration; + +import club.joylink.xiannccda.exception.BusinessExceptionAssertEnum; +import com.alibaba.fastjson2.JSON; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.ProblemDetail; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.simp.config.ChannelRegistration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.messaging.simp.stomp.StompCommand; +import org.springframework.messaging.simp.stomp.StompHeaderAccessor; +import org.springframework.messaging.support.ChannelInterceptor; +import org.springframework.messaging.support.MessageHeaderAccessor; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication; +import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider; +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 { + + @Autowired + JwtAuthenticationProvider jwtAuthenticationProvider; + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry.addEndpoint("/ws-default").setAllowedOrigins("*"); + } + + @Override + public void configureMessageBroker(MessageBrokerRegistry registry) { + registry.enableSimpleBroker("/queue"); + } + + static final String Bearer = "Bearer "; + + @Override + public void configureClientInboundChannel(ChannelRegistration registration) { + registration.interceptors(new ChannelInterceptor() { + @Override + public Message preSend(Message message, MessageChannel channel) { + StompHeaderAccessor accessor = + MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class); + if (StompCommand.CONNECT.equals(accessor.getCommand())) { + try { + boolean auth = false; + List list = accessor.getNativeHeader("Authorization"); + if (list != null && list.size() == 1) { + String authorization = list.get(0); + if (authorization.startsWith(Bearer)) { + String token = authorization.substring(Bearer.length()).trim(); + Authentication user = jwtAuthenticationProvider.authenticate( + new BearerTokenAuthenticationToken(token)); + accessor.setUser(user); + auth = true; + } + } + if (!auth) { + throw new AuthenticationException("认证失败") { + @Override + public String getMessage() { + return super.getMessage(); + } + }; + } + } catch (AuthenticationException e) { + throw e; // 待寻找优雅的方案 + } + } + return message; + } + + }); + } +} diff --git a/src/main/java/club/joylink/xiannccda/ws/TestController.java b/src/main/java/club/joylink/xiannccda/ws/TestController.java new file mode 100644 index 0000000..fc4d273 --- /dev/null +++ b/src/main/java/club/joylink/xiannccda/ws/TestController.java @@ -0,0 +1,20 @@ +package club.joylink.xiannccda.ws; + +import club.joylink.xiannccda.entity.User; +import java.time.LocalDateTime; +import org.springframework.messaging.simp.annotation.SubscribeMapping; +import org.springframework.stereotype.Controller; + +@Controller +public class TestController { + + @SubscribeMapping("/queue/test") + public User testSubscription() { + User user = new User(); + user.setId(1); + user.setName("sheng"); + user.setRegisterTime(LocalDateTime.now()); + return user; + } + +}