Skip to content

Commit 64dd0ab

Browse files
committed
add alternative authorization
1 parent 1192d46 commit 64dd0ab

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
<modelVersion>4.0.0</modelVersion>
1212
<artifactId>websocket-server</artifactId>
13-
<version>1.0.0</version>
13+
<version>1.0.4</version>
1414
<name>WebsocketServer</name>
1515
<packaging>jar</packaging>
1616

src/main/java/info/unterrainer/websocketserver/WsOauthHandlerBase.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
import java.io.EOFException;
44
import java.io.IOException;
5+
import java.util.Set;
6+
import java.util.concurrent.ConcurrentHashMap;
7+
8+
import org.eclipse.jetty.websocket.api.Session;
59

610
import info.unterrainer.oauthtokenmanager.OauthTokenManager;
711
import io.javalin.websocket.WsCloseContext;
@@ -14,19 +18,55 @@
1418
public class WsOauthHandlerBase extends WsHandlerBase {
1519

1620
private OauthTokenManager tokenHandler;
21+
private Set<WsConnectContext> clientsConnected = ConcurrentHashMap.newKeySet();
22+
private Set<WsConnectContext> clientsQuarantined = ConcurrentHashMap.newKeySet();
1723

1824
void setTokenHandler(OauthTokenManager tokenHandler) {
1925
this.tokenHandler = tokenHandler;
2026
}
2127

28+
public void removeClient(Session session) {
29+
log.debug("Removing client: [{}]", session.getRemoteAddress());
30+
clientsConnected.removeIf(client -> client.session.equals(session));
31+
clientsQuarantined.removeIf(client -> client.session.equals(session));
32+
}
33+
34+
public WsConnectContext getClient(Session session) {
35+
log.debug("Getting client: [{}]", session.getRemoteAddress());
36+
return clientsConnected.stream().filter(client -> client.session.equals(session)).findFirst().orElse(null);
37+
}
38+
39+
public WsConnectContext getQuarantinedClient(Session session) {
40+
log.debug("Getting quarantined client: [{}]", session.getRemoteAddress());
41+
return clientsQuarantined.stream().filter(client -> client.session.equals(session)).findFirst().orElse(null);
42+
}
43+
44+
public boolean isQuarantined(Session session) {
45+
log.debug("Checking if client is quarantined: [{}]", session.getRemoteAddress());
46+
return clientsQuarantined.stream().anyMatch(client -> client.session.equals(session));
47+
}
48+
49+
public boolean isConnected(Session session) {
50+
log.debug("Checking if client is connected: [{}]", session.getRemoteAddress());
51+
return clientsConnected.stream().anyMatch(client -> client.session.equals(session));
52+
}
53+
2254
@Override
2355
public void onConnect(WsConnectContext ctx) throws Exception {
2456
log.debug("New client tries to connect: [{}]", ctx.session.getRemoteAddress());
2557
String token = ctx.header("Authorization");
58+
if (token == null || token.isEmpty()) {
59+
log.warn("No token provided for client: [{}]\nSending connection into quarantine.",
60+
ctx.session.getRemoteAddress());
61+
clientsQuarantined.add(ctx);
62+
return;
63+
}
2664
log.debug("New client token: [{}]", token);
2765
try {
2866
tokenHandler.checkAccess(token);
67+
clientsConnected.add(ctx);
2968
} catch (Exception e) {
69+
log.debug("Token validation failed for client [{}]. Disconnecting.", ctx.session.getRemoteAddress(), e);
3070
ctx.session.close();
3171
return;
3272
}
@@ -35,11 +75,33 @@ public void onConnect(WsConnectContext ctx) throws Exception {
3575
@Override
3676
public void onMessage(WsMessageContext ctx) throws Exception {
3777
log.debug("Received from [{}]: [{}]", ctx.session.getRemoteAddress(), ctx.message());
78+
if (isQuarantined(ctx.session)) {
79+
log.warn("Client [{}] is quarantined, checking message for standard authorization-bearer-token.",
80+
ctx.session.getRemoteAddress());
81+
if (ctx.message() == null || !ctx.message().startsWith("Bearer ")) {
82+
log.warn("Invalid message from quarantined client [{}]. Disconnecting.",
83+
ctx.session.getRemoteAddress());
84+
removeClient(ctx.session);
85+
ctx.session.close();
86+
return;
87+
}
88+
try {
89+
tokenHandler.checkAccess(ctx.message());
90+
WsConnectContext client = getQuarantinedClient(ctx.session);
91+
clientsQuarantined.removeIf(c -> c.session.equals(ctx.session));
92+
clientsConnected.add(client);
93+
} catch (Exception e) {
94+
ctx.session.close();
95+
log.debug("Token validation failed for client [{}]. Disconnecting.", ctx.session.getRemoteAddress(), e);
96+
return;
97+
}
98+
}
3899
}
39100

40101
@Override
41102
public void onClose(WsCloseContext ctx) throws Exception {
42103
log.debug("Disconnected client: [{}]", ctx.session.getRemoteAddress());
104+
removeClient(ctx.session);
43105
}
44106

45107
@Override
@@ -50,5 +112,6 @@ public void onError(WsErrorContext ctx) throws Exception {
50112
} else {
51113
log.error("Unexpected error on [{}].", ctx.session.getRemoteAddress(), t);
52114
}
115+
removeClient(ctx.session);
53116
}
54117
}

0 commit comments

Comments
 (0)