Skip to content

Commit f7d1669

Browse files
author
lastpeony
committed
issue #4809 jwt blacklist implementation and stop play/ publish using jwt
api call
1 parent 7c73103 commit f7d1669

16 files changed

+760
-21
lines changed

src/main/java/io/antmedia/AntMediaApplicationAdapter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,6 +1508,8 @@ public static boolean updateAppSettingsFile(String appName, AppSettings newAppse
15081508
store.put(AppSettings.SETTINGS_PUBLISH_JWT_CONTROL_ENABLED, String.valueOf(newAppsettings.isPublishJwtControlEnabled()));
15091509
store.put(AppSettings.SETTINGS_PLAY_JWT_CONTROL_ENABLED, String.valueOf(newAppsettings.isPlayJwtControlEnabled()));
15101510
store.put(AppSettings.SETTINGS_JWT_STREAM_SECRET_KEY, newAppsettings.getJwtStreamSecretKey() != null ? newAppsettings.getJwtStreamSecretKey() : "");
1511+
store.put(AppSettings.SETTINGS_JWT_BLACKLIST_ENABLED, String.valueOf(newAppsettings.isJwtBlacklistEnabled()));
1512+
15111513

15121514
store.put(AppSettings.SETTINGS_WEBRTC_ENABLED, String.valueOf(newAppsettings.isWebRTCEnabled()));
15131515
store.put(AppSettings.SETTINGS_WEBRTC_FRAME_RATE, String.valueOf(newAppsettings.getWebRTCFrameRate()));

src/main/java/io/antmedia/AppSettings.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ public class AppSettings implements Serializable{
265265
public static final String SETTINGS_JWT_SECRET_KEY = "settings.jwtSecretKey";
266266

267267
public static final String SETTINGS_JWT_CONTROL_ENABLED = "settings.jwtControlEnabled";
268+
public static final String SETTINGS_JWT_BLACKLIST_ENABLED = "settings.jwtBlacklistEnabled";
268269

269270
public static final String SETTINGS_IP_FILTER_ENABLED = "settings.ipFilterEnabled";
270271

@@ -1283,6 +1284,8 @@ public class AppSettings implements Serializable{
12831284
@Value( "${"+SETTINGS_JWT_CONTROL_ENABLED+":false}" )
12841285
private boolean jwtControlEnabled;
12851286

1287+
@Value( "${"+SETTINGS_JWT_BLACKLIST_ENABLED+":false}" )
1288+
private boolean jwtBlacklistEnabled;
12861289
/**
12871290
* Application IP Filter Enabled
12881291
*/
@@ -2600,6 +2603,13 @@ public boolean isJwtControlEnabled() {
26002603
return jwtControlEnabled;
26012604
}
26022605

2606+
public void setJwtBlacklistEnabled(boolean jwtBlacklistEnabled){
2607+
this.jwtBlacklistEnabled = jwtBlacklistEnabled;
2608+
}
2609+
2610+
public boolean isJwtBlacklistEnabled() {
2611+
return jwtBlacklistEnabled;
2612+
}
26032613
public void setJwtControlEnabled(boolean jwtControlEnabled) {
26042614
this.jwtControlEnabled = jwtControlEnabled;
26052615
}

src/main/java/io/antmedia/datastore/db/DataStore.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import java.util.List;
1111
import java.util.Map;
1212

13+
import io.antmedia.rest.model.Result;
14+
import io.antmedia.security.ITokenService;
1315
import org.apache.commons.lang3.RandomStringUtils;
1416
import org.apache.commons.lang3.exception.ExceptionUtils;
1517
import org.slf4j.Logger;
@@ -424,6 +426,27 @@ public List<Token> listAllTokens (Map<String, String> tokenMap, String streamId,
424426

425427
public abstract boolean deleteToken (String tokenId);
426428

429+
/**
430+
* Delete specific token from blacklist.
431+
* @param tokenId id of the token
432+
*/
433+
public abstract boolean deleteTokenFromBlacklist (String tokenId);
434+
435+
/**
436+
* Get all tokens from jwt blacklist.
437+
*/
438+
public abstract ArrayList<String> getJwtBlacklist();
439+
440+
/**
441+
* Delete all expired tokens from jwt blacklist.
442+
*/
443+
public abstract Result deleteAllExpiredJwtFromBlacklist(ITokenService tokenService);
444+
445+
/**
446+
* Delete all tokens from jwt blacklist.
447+
*/
448+
public abstract void clearJwtBlacklist();
449+
427450
/**
428451
* retrieve specific token
429452
* @param tokenId id of the token
@@ -1352,7 +1375,18 @@ public List<WebRTCViewerInfo> getWebRTCViewerList(Map<String, String> webRTCView
13521375
* @param metaData new meta data
13531376
*/
13541377
public abstract boolean updateStreamMetaData(String streamId, String metaData);
1355-
1378+
1379+
/**
1380+
* Add jwt token to black list.
1381+
* @param token which will be added to black list.
1382+
*/
1383+
public abstract boolean addTokenToBlacklist(Token token);
1384+
1385+
/**
1386+
* Get token from black list.
1387+
* @param tokenId id of the token.
1388+
*/
1389+
public abstract Token getTokenFromBlacklist(String tokenId);
13561390

13571391
//**************************************
13581392
//ATTENTION: Write function descriptions while adding new functions

src/main/java/io/antmedia/datastore/db/InMemoryDataStore.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
import java.util.Map.Entry;
1212
import java.util.Set;
1313
import java.util.regex.Pattern;
14+
15+
import io.antmedia.rest.model.Result;
16+
import io.antmedia.security.ITokenService;
1417
import org.apache.commons.io.FilenameUtils;
1518
import org.apache.commons.lang3.RandomStringUtils;
1619
import org.apache.commons.lang3.exception.ExceptionUtils;
@@ -900,6 +903,26 @@ public boolean deleteToken(String tokenId) {
900903

901904
}
902905

906+
@Override
907+
public boolean deleteTokenFromBlacklist(String tokenId) {
908+
return false;
909+
}
910+
911+
@Override
912+
public ArrayList<String> getJwtBlacklist() {
913+
return null;
914+
}
915+
916+
@Override
917+
public Result deleteAllExpiredJwtFromBlacklist(ITokenService tokenService) {
918+
return null;
919+
}
920+
921+
@Override
922+
public void clearJwtBlacklist() {
923+
924+
}
925+
903926
@Override
904927
public Token getToken(String tokenId) {
905928

@@ -1022,4 +1045,14 @@ public boolean updateStreamMetaData(String streamId, String metaData) {
10221045
}
10231046
return result;
10241047
}
1048+
1049+
@Override
1050+
public boolean addTokenToBlacklist(Token token) {
1051+
return false;
1052+
}
1053+
1054+
@Override
1055+
public Token getTokenFromBlacklist(String tokenId) {
1056+
return null;
1057+
}
10251058
}

src/main/java/io/antmedia/datastore/db/MapBasedDataStore.java

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99
import java.util.Map;
1010
import java.util.Map.Entry;
1111
import java.util.Set;
12+
import java.util.concurrent.atomic.AtomicInteger;
1213
import java.util.regex.Pattern;
1314

15+
import io.antmedia.rest.model.Result;
16+
import io.antmedia.security.ITokenService;
1417
import org.apache.commons.io.FilenameUtils;
1518
import org.apache.commons.lang3.RandomStringUtils;
1619
import org.apache.commons.lang3.exception.ExceptionUtils;
@@ -41,6 +44,8 @@ public abstract class MapBasedDataStore extends DataStore {
4144
protected Map<String, String> vodMap;
4245
protected Map<String, String> detectionMap;
4346
protected Map<String, String> tokenMap;
47+
protected Map<String, String> tokenBlacklistMap;
48+
4449
protected Map<String, String> subscriberMap;
4550
protected Map<String, String> conferenceRoomMap;
4651
protected Map<String, String> webRTCViewerMap;
@@ -943,6 +948,65 @@ public boolean deleteToken(String tokenId) {
943948
return result;
944949
}
945950

951+
@Override
952+
public boolean deleteTokenFromBlacklist(String tokenId) {
953+
boolean result;
954+
955+
synchronized (this) {
956+
result = tokenBlacklistMap.remove(tokenId) != null;
957+
}
958+
return result;
959+
}
960+
961+
@Override
962+
public ArrayList<String> getJwtBlacklist(){
963+
964+
synchronized (this){
965+
return new ArrayList<>(tokenBlacklistMap.keySet());
966+
967+
}
968+
969+
}
970+
971+
@Override
972+
public Result deleteAllExpiredJwtFromBlacklist(ITokenService tokenService){
973+
logger.info("Deleting all expired JWTs from black list.");
974+
AtomicInteger deletedTokenCount = new AtomicInteger();
975+
976+
synchronized (this){
977+
tokenBlacklistMap.forEach((key, value) -> {
978+
Token token = gson.fromJson(value,Token.class);
979+
String tokenId = token.getTokenId();
980+
if(!tokenService.verifyJwt(tokenId,token.getStreamId(),token.getType())){
981+
if(deleteTokenFromBlacklist(tokenId)){
982+
deletedTokenCount.getAndIncrement();
983+
}else{
984+
logger.warn("Couldn't delete JWT:" + tokenId);
985+
}
986+
}
987+
});
988+
}
989+
990+
if(deletedTokenCount.get() > 0){
991+
final String successMsg = deletedTokenCount+" JWT deleted successfully from black list.";
992+
logger.info(successMsg);
993+
return new Result(true, successMsg);
994+
}else{
995+
final String failMsg = "No JWT deleted from black list.";
996+
logger.warn(failMsg);
997+
return new Result(false, failMsg);
998+
999+
}
1000+
1001+
}
1002+
1003+
@Override
1004+
public void clearJwtBlacklist(){
1005+
synchronized (this) {
1006+
tokenBlacklistMap.clear();
1007+
}
1008+
}
1009+
9461010
@Override
9471011
public Token getToken(String tokenId) {
9481012
return super.getToken(tokenMap, tokenId, gson);
@@ -1055,4 +1119,30 @@ public Broadcast getBroadcastFromMap(String streamId)
10551119
return null;
10561120
}
10571121

1122+
@Override
1123+
public boolean addTokenToBlacklist(Token token) {
1124+
boolean result = false;
1125+
1126+
synchronized (this) {
1127+
1128+
if (token.getStreamId() != null && token.getTokenId() != null) {
1129+
1130+
try {
1131+
tokenBlacklistMap.put(token.getTokenId(), gson.toJson(token));
1132+
result = true;
1133+
} catch (Exception e) {
1134+
logger.error(ExceptionUtils.getStackTrace(e));
1135+
}
1136+
}
1137+
}
1138+
return result;
1139+
1140+
}
1141+
1142+
@Override
1143+
public Token getTokenFromBlacklist(String tokenId) {
1144+
return super.getToken(tokenBlacklistMap, tokenId, gson);
1145+
1146+
}
1147+
10581148
}

src/main/java/io/antmedia/datastore/db/MapDBStore.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,17 @@
44
import java.io.IOException;
55
import java.nio.file.Files;
66
import java.util.ArrayList;
7-
import java.util.Iterator;
87
import java.util.List;
9-
import java.util.Set;
10-
import java.util.Map.Entry;
118

9+
import io.antmedia.datastore.db.types.Token;
1210
import org.apache.commons.lang3.exception.ExceptionUtils;
1311
import org.mapdb.DB;
1412
import org.mapdb.DBMaker;
1513
import org.mapdb.Serializer;
1614
import org.slf4j.Logger;
1715
import org.slf4j.LoggerFactory;
1816

19-
import io.antmedia.datastore.db.types.Broadcast;
2017
import io.antmedia.datastore.db.types.StreamInfo;
21-
import io.antmedia.muxer.IAntMediaStreamHandler;
2218
import io.vertx.core.Vertx;
2319

2420

@@ -33,6 +29,8 @@ public class MapDBStore extends MapBasedDataStore {
3329
private static final String VOD_MAP_NAME = "VOD";
3430
private static final String DETECTION_MAP_NAME = "DETECTION";
3531
private static final String TOKEN = "TOKEN";
32+
private static final String TOKEN_BLACKLIST = "TOKEN_BLACKLIST";
33+
3634
private static final String SUBSCRIBER = "SUBSCRIBER";
3735
private static final String CONFERENCE_ROOM_MAP_NAME = "CONFERENCE_ROOM";
3836
private static final String WEBRTC_VIEWER = "WEBRTC_VIEWER";
@@ -73,6 +71,10 @@ public MapDBStore(String dbName, Vertx vertx) {
7371
webRTCViewerMap = db.treeMap(WEBRTC_VIEWER).keySerializer(Serializer.STRING).valueSerializer(Serializer.STRING)
7472
.counterEnable().createOrOpen();
7573

74+
tokenBlacklistMap = db.treeMap(TOKEN_BLACKLIST).keySerializer(Serializer.STRING).valueSerializer(Serializer.STRING)
75+
.counterEnable().createOrOpen();
76+
77+
7678
timerId = vertx.setPeriodic(5000, id ->
7779

7880
vertx.executeBlocking(b -> {
@@ -124,7 +126,10 @@ public void close(boolean deleteDB) {
124126
public void clearStreamInfoList(String streamId) {
125127
//used in mongo for cluster mode. useless here.
126128
}
127-
129+
130+
131+
132+
128133
@Override
129134
public List<StreamInfo> getStreamInfoList(String streamId) {
130135
return new ArrayList<>();

src/main/java/io/antmedia/datastore/db/MongoStore.java

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import java.util.List;
1313
import java.util.regex.Pattern;
1414

15+
import io.antmedia.rest.model.Result;
16+
import io.antmedia.security.ITokenService;
1517
import org.apache.commons.io.FilenameUtils;
1618
import org.apache.commons.lang3.RandomStringUtils;
1719
import org.apache.commons.lang3.exception.ExceptionUtils;
@@ -94,7 +96,6 @@ public MongoStore(String host, String username, String password, String dbName)
9496
subscriberDatastore = Morphia.createDatastore(mongoClient, dbName + "_subscriber");
9597
detectionMap = Morphia.createDatastore(mongoClient, dbName + "detection");
9698
conferenceRoomDatastore = Morphia.createDatastore(mongoClient, dbName + "room");
97-
9899
//*************************************************
99100
//do not create data store for each type as we do above
100101
//*************************************************
@@ -107,7 +108,7 @@ public MongoStore(String host, String username, String password, String dbName)
107108
vodDatastore.getMapper().mapPackage("io.antmedia.datastore.db.types");
108109
detectionMap.getMapper().mapPackage("io.antmedia.datastore.db.types");
109110
conferenceRoomDatastore.getMapper().mapPackage("io.antmedia.datastore.db.types");
110-
111+
111112
tokenDatastore.ensureIndexes();
112113
subscriberDatastore.ensureIndexes();
113114
datastore.ensureIndexes();
@@ -1196,6 +1197,26 @@ public boolean deleteToken(String tokenId) {
11961197
return result;
11971198
}
11981199

1200+
@Override
1201+
public boolean deleteTokenFromBlacklist(String tokenId) {
1202+
return false;
1203+
}
1204+
1205+
@Override
1206+
public ArrayList<String> getJwtBlacklist() {
1207+
return null;
1208+
}
1209+
1210+
@Override
1211+
public Result deleteAllExpiredJwtFromBlacklist(ITokenService tokenService) {
1212+
return null;
1213+
}
1214+
1215+
@Override
1216+
public void clearJwtBlacklist() {
1217+
1218+
}
1219+
11991220
@Override
12001221
public Token getToken(String tokenId) {
12011222
Token token = null;
@@ -1429,4 +1450,15 @@ public boolean updateStreamMetaData(String streamId, String metaData) {
14291450
}
14301451
return false;
14311452
}
1453+
1454+
@Override
1455+
public boolean addTokenToBlacklist(Token token) {
1456+
1457+
return false;
1458+
}
1459+
1460+
@Override
1461+
public Token getTokenFromBlacklist(String tokenId) {
1462+
return null;
1463+
}
14321464
}

0 commit comments

Comments
 (0)