websocket支持握手时鉴权

This commit is contained in:
远方 2022-02-15 20:52:27 +08:00
parent ec8b4a8392
commit fbe5e24e41
8 changed files with 42 additions and 35 deletions

View File

@ -141,6 +141,9 @@ CIM采用业内主流开源技术构建易于扩展和使用并完美支
版本:4.1.0/时间:2022-02-15
1.websocket支持在握手时鉴权验证
2.websocketPath 由 "/" 变更为 "" wss和ws链接地址后面不需要加/
https://www.yuque.com/yuanfangxiyang/ma4ytb/vvy3iz#mmdUX
2.支持自定义配置websocketPath

View File

@ -10,7 +10,6 @@ import com.farsunset.cim.sdk.server.handler.CIMRequestHandler;
import com.farsunset.cim.sdk.server.model.SentBody;
import com.farsunset.cim.service.SessionService;
import io.netty.channel.Channel;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
@ -49,6 +48,7 @@ public class CIMConfig implements CIMRequestHandler, ApplicationListener<Applica
return new CIMNioSocketAcceptor.Builder()
.setAppPort(properties.getAppPort())
.setWebsocketPort(properties.getWebsocketPort())
.setWebsocketPath(properties.getWebsocketPath())
.setHandshakePredicate(handshakePredicate)
.setOuterRequestHandler(this)
.build();

View File

@ -54,6 +54,15 @@ public class CIMProperties {
public static class Websocket {
private Integer port;
private String path;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public Integer getPort() {
return port;
@ -71,4 +80,9 @@ public class CIMProperties {
public Integer getWebsocketPort() {
return websocket.port;
}
public String getWebsocketPath() {
return websocket.path;
}
}

View File

@ -34,7 +34,8 @@ spring.jpa.hibernate.naming.physical-strategy= org.hibernate.boot.model.naming.P
# Redis Config #
##################################################################
spring.redis.host=127.0.0.1
spring.redis.password=RDSV587
spring.redis.port=6379
#spring.redis.password=redisv587
spring.redis.database=12
spring.redis.lettuce.pool.max-active=10
spring.redis.lettuce.pool.max-wait= 10s
@ -62,6 +63,7 @@ spring.messages.basename=i18n/messages
#commented to disable this port.
cim.app.port=23456
cim.websocket.port=34567
cim.websocket.path=/
#please setting your p12 info and appId.
cim.apns.p12.file=/apns/app.p12

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.60.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.60.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.60.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec-http:4.1.60.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.60.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.60.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.60.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-transport-native-epoll:linux-x86_64:4.1.60.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-transport-native-unix-common:4.1.60.Final" level="project" />
<orderEntry type="library" name="Maven: com.google.protobuf:protobuf-java:3.11.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
</component>
</module>

View File

@ -58,7 +58,7 @@ import java.util.function.Predicate;
public class CIMNioSocketAcceptor extends SimpleChannelInboundHandler<SentBody>{
private static final Logger LOGGER = LoggerFactory.getLogger(CIMNioSocketAcceptor.class);
private static final int PONG_TIME_OUT_COUNT = 3;
private static final int PONG_TIME_OUT_COUNT = 3;
private final ThreadFactory bossThreadFactory;
private final ThreadFactory workerThreadFactory;
@ -70,6 +70,7 @@ public class CIMNioSocketAcceptor extends SimpleChannelInboundHandler<SentBody>{
private final Integer appPort;
private final Integer webPort;
private final String websocketPath;
private final CIMRequestHandler outerRequestHandler;
private final HandshakeHandler handshakeHandler;
@ -90,6 +91,7 @@ public class CIMNioSocketAcceptor extends SimpleChannelInboundHandler<SentBody>{
this.appPort = builder.appPort;
this.outerRequestHandler = builder.outerRequestHandler;
this.handshakeHandler = new HandshakeHandler(builder.handshakePredicate);
this.websocketPath = builder.websocketPath == null ? "/" : builder.websocketPath;
bossThreadFactory = r -> {
Thread thread = new Thread(r);
@ -145,8 +147,8 @@ public class CIMNioSocketAcceptor extends SimpleChannelInboundHandler<SentBody>{
}
}
public void destroy() {
this.destroy(appBossGroup,appWorkerGroup);
public void destroy() {
this.destroy(appBossGroup,appWorkerGroup);
this.destroy(webBossGroup,webWorkerGroup);
}
@ -189,7 +191,7 @@ public class CIMNioSocketAcceptor extends SimpleChannelInboundHandler<SentBody>{
ch.pipeline().addLast(new HttpServerCodec());
ch.pipeline().addLast(new ChunkedWriteHandler());
ch.pipeline().addLast(new HttpObjectAggregator(4 * 1024));
ch.pipeline().addLast(new WebSocketServerProtocolHandler("",false));
ch.pipeline().addLast(new WebSocketServerProtocolHandler(websocketPath,false));
ch.pipeline().addLast(handshakeHandler);
ch.pipeline().addLast(new WebMessageDecoder());
ch.pipeline().addLast(new WebMessageEncoder());
@ -301,6 +303,7 @@ public class CIMNioSocketAcceptor extends SimpleChannelInboundHandler<SentBody>{
private Integer appPort;
private Integer webPort;
private String websocketPath;
private CIMRequestHandler outerRequestHandler;
private Predicate<HandshakeEvent> handshakePredicate;
@ -314,6 +317,11 @@ public class CIMNioSocketAcceptor extends SimpleChannelInboundHandler<SentBody>{
return this;
}
public Builder setWebsocketPath(String websocketPath) {
this.websocketPath = websocketPath;
return this;
}
/**
* 设置应用层的sentBody处理handler
*/

View File

@ -38,16 +38,20 @@ import java.util.function.Predicate;
@ChannelHandler.Sharable
public class HandshakeHandler extends ChannelInboundHandlerAdapter {
private final Predicate<HandshakeEvent> handshakePredicate;
/*
客户端接收到的CloseEvent事件类型
客户端可通过该code判断是握手鉴权失败
*/
private static final int UNAUTHORIZED_CODE = 4001;
private final WebSocketCloseStatus closeStatus = new WebSocketCloseStatus(HttpResponseStatus.UNAUTHORIZED.code(),HttpResponseStatus.UNAUTHORIZED.reasonPhrase());
private final Predicate<HandshakeEvent> handshakePredicate;
public HandshakeHandler(Predicate<HandshakeEvent> handshakePredicate) {
this.handshakePredicate = handshakePredicate;
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
super.userEventTriggered(ctx, evt);
@ -67,7 +71,7 @@ public class HandshakeHandler extends ChannelInboundHandlerAdapter {
* 鉴权不通过关闭链接
*/
if (!handshakePredicate.test(HandshakeEvent.of(event))) {
context.channel().writeAndFlush(new CloseWebSocketFrame(closeStatus)).addListener(ChannelFutureListener.CLOSE);
context.channel().writeAndFlush(new CloseWebSocketFrame(UNAUTHORIZED_CODE,HttpResponseStatus.UNAUTHORIZED.reasonPhrase())).addListener(ChannelFutureListener.CLOSE);
}
}
}