diff --git a/application/src/main/java/org/thingsboard/server/controller/AuthController.java b/application/src/main/java/org/thingsboard/server/controller/AuthController.java index 84e8f3df9d..d098b1edec 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AuthController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AuthController.java @@ -43,6 +43,8 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.event.UserAuthDataChangedEvent; +import org.thingsboard.server.common.data.security.event.UserCredentialsInvalidationEvent; +import org.thingsboard.server.common.data.security.event.UserSessionInvalidationEvent; import org.thingsboard.server.common.data.security.model.SecuritySettings; import org.thingsboard.server.common.data.security.model.UserPasswordPolicy; import org.thingsboard.server.dao.audit.AuditLogService; @@ -125,7 +127,7 @@ public class AuthController extends BaseController { sendEntityNotificationMsg(getTenantId(), userCredentials.getUserId(), EdgeEventActionType.CREDENTIALS_UPDATED); - eventPublisher.publishEvent(new UserAuthDataChangedEvent(securityUser.getId(), securityUser.getSessionId(), false)); + eventPublisher.publishEvent(new UserCredentialsInvalidationEvent(securityUser.getId())); ObjectNode response = JacksonUtil.newObjectNode(); response.put("token", tokenFactory.createAccessJwtToken(securityUser).getToken()); response.put("refreshToken", tokenFactory.createRefreshToken(securityUser).getToken()); @@ -303,7 +305,7 @@ public class AuthController extends BaseController { String email = user.getEmail(); mailService.sendPasswordWasResetEmail(loginUrl, email); - eventPublisher.publishEvent(new UserAuthDataChangedEvent(securityUser.getId(), securityUser.getSessionId(), false)); + eventPublisher.publishEvent(new UserCredentialsInvalidationEvent(securityUser.getId())); return tokenFactory.createTokenPair(securityUser); } else { @@ -359,7 +361,7 @@ public class AuthController extends BaseController { user.getTenantId(), user.getCustomerId(), user.getId(), user.getName(), user.getId(), null, ActionType.LOGOUT, null, clientAddress, browser, os, device); - eventPublisher.publishEvent(new UserAuthDataChangedEvent(user.getId(), user.getSessionId(), false)); + eventPublisher.publishEvent(new UserSessionInvalidationEvent(user.getSessionId())); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/controller/UserController.java b/application/src/main/java/org/thingsboard/server/controller/UserController.java index 6f19cde2e8..fe07c4b49c 100644 --- a/application/src/main/java/org/thingsboard/server/controller/UserController.java +++ b/application/src/main/java/org/thingsboard/server/controller/UserController.java @@ -44,6 +44,7 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.event.UserAuthDataChangedEvent; +import org.thingsboard.server.common.data.security.event.UserCredentialsInvalidationEvent; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.user.TbUserService; import org.thingsboard.server.service.security.model.JwtTokenPair; @@ -371,7 +372,7 @@ public class UserController extends BaseController { userService.setUserCredentialsEnabled(tenantId, userId, userCredentialsEnabled); if (!userCredentialsEnabled) { - eventPublisher.publishEvent(new UserAuthDataChangedEvent(userId, null, true)); + eventPublisher.publishEvent(new UserCredentialsInvalidationEvent(userId)); } } catch (Exception e) { throw handleException(e); diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/TokenOutdatingService.java b/application/src/main/java/org/thingsboard/server/service/security/auth/TokenOutdatingService.java index 6bb74ed758..d5f62037af 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/TokenOutdatingService.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/TokenOutdatingService.java @@ -19,16 +19,14 @@ import io.jsonwebtoken.Claims; import lombok.RequiredArgsConstructor; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; -import org.springframework.transaction.event.TransactionalEventListener; -import org.thingsboard.server.cache.usersUpdateTime.UsersUpdateTimeCacheEvictEvent; +import org.thingsboard.server.cache.TbCacheValueWrapper; +import org.thingsboard.server.cache.TbTransactionalCache; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.security.event.UserAuthDataChangedEvent; import org.thingsboard.server.common.data.security.model.JwtToken; import org.thingsboard.server.config.JwtSettings; -import org.thingsboard.server.dao.entity.AbstractCachedEntityService; import org.thingsboard.server.service.security.model.token.JwtTokenFactory; -import java.util.HashMap; import java.util.Optional; import static java.util.concurrent.TimeUnit.MILLISECONDS; @@ -36,13 +34,14 @@ import static java.util.concurrent.TimeUnit.SECONDS; @Service @RequiredArgsConstructor -public class TokenOutdatingService extends AbstractCachedEntityService, UsersUpdateTimeCacheEvictEvent> { +public class TokenOutdatingService { + private final TbTransactionalCache cache; private final JwtTokenFactory tokenFactory; private final JwtSettings jwtSettings; @EventListener(classes = UserAuthDataChangedEvent.class) public void onUserAuthDataChanged(UserAuthDataChangedEvent event) { - processUserSessions(event); + cache.put(event.getId(), event.getTs()); } public boolean isOutdated(JwtToken token, UserId userId) { @@ -50,48 +49,36 @@ public class TokenOutdatingService extends AbstractCachedEntityService { - if (outdatageTime.get().get(sessionId) != null && System.currentTimeMillis() - outdatageTime.get().get(sessionId) <= SECONDS.toMillis(jwtSettings.getRefreshTokenExpTime())) { - return MILLISECONDS.toSeconds(issueTime) < MILLISECONDS.toSeconds(outdatageTime.get().get(sessionId)); + + Boolean isUserIdOutdated = Optional.ofNullable(cache.get(userId.toString())) + .map(outdatageTimeByUserId -> { + if (refreshTokenNotExpired(outdatageTimeByUserId.get(), System.currentTimeMillis())) { + return accessTokenNotExpired(issueTime, outdatageTimeByUserId.get()); } else { - /* - * Means that since the outdating has passed more than - * the lifetime of refresh token (the longest lived) - * and there is no need to store outdatage time anymore - * as all the tokens issued before the outdatage time - * are now expired by themselves - * */ - handleEvictEvent(new UsersUpdateTimeCacheEvictEvent(userId, sessionId)); return false; } }) .orElse(false); + + if (!isUserIdOutdated) { + return Optional.ofNullable(cache.get(sessionId)).map(outdatageTimeBySessionId -> { + if (refreshTokenNotExpired(outdatageTimeBySessionId.get(), System.currentTimeMillis())) { + return accessTokenNotExpired(issueTime, outdatageTimeBySessionId.get()); + } else { + return false; + } + } + ).orElse(false); + } + + return isUserIdOutdated; } - @TransactionalEventListener(classes = UsersUpdateTimeCacheEvictEvent.class) - @Override - public void handleEvictEvent(UsersUpdateTimeCacheEvictEvent event) { - HashMap userSessions = cache.get(event.getUserId()).get(); - if (userSessions != null) { - userSessions.remove(event.getSessionId()); - cache.put(event.getUserId(), userSessions); - } + private boolean accessTokenNotExpired(long issueTime, Long outdatageTime) { + return MILLISECONDS.toSeconds(issueTime) < MILLISECONDS.toSeconds(outdatageTime); } - private void processUserSessions(UserAuthDataChangedEvent event) { - if (cache.get(event.getUserId()) != null) { - HashMap userSessions = cache.get(event.getUserId()).get(); - if (event.isDropAllSessions()) { - userSessions.replaceAll((k, v) -> event.getTs()); - } else { - userSessions.put(event.getSessionId(), event.getTs()); - } - cache.put(event.getUserId(), userSessions); - } else { - cache.put(event.getUserId(), new HashMap<>() {{ - put(event.getSessionId(), event.getTs()); - }}); - } + private boolean refreshTokenNotExpired(Long outdatageTime, long currentTime) { + return currentTime - outdatageTime <= SECONDS.toMillis(jwtSettings.getRefreshTokenExpTime()); } } diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenAuthenticationProvider.java b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenAuthenticationProvider.java index 8003cfd012..700bbd7f74 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenAuthenticationProvider.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenAuthenticationProvider.java @@ -66,7 +66,7 @@ public class RefreshTokenAuthenticationProvider implements AuthenticationProvide } else { securityUser = authenticateByPublicId(principal.getValue()); } - + securityUser.setSessionId(unsafeUser.getSessionId()); if (tokenOutdatingService.isOutdated(rawAccessToken, securityUser.getId())) { throw new CredentialsExpiredException("Token is outdated"); } diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java b/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java index 110ed5702b..dca366df18 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java @@ -120,7 +120,9 @@ public class JwtTokenFactory { if (customerId != null) { securityUser.setCustomerId(new CustomerId(UUID.fromString(customerId))); } - securityUser.setSessionId(claims.get(SESSION_ID, String.class)); + if (claims.get(SESSION_ID, String.class) != null) { + securityUser.setSessionId(claims.get(SESSION_ID, String.class)); + } UserPrincipal principal; if (securityUser.getAuthority() != Authority.PRE_VERIFICATION_TOKEN) { @@ -163,7 +165,9 @@ public class JwtTokenFactory { UserPrincipal principal = new UserPrincipal(isPublic ? UserPrincipal.Type.PUBLIC_ID : UserPrincipal.Type.USER_NAME, subject); SecurityUser securityUser = new SecurityUser(new UserId(UUID.fromString(claims.get(USER_ID, String.class)))); securityUser.setUserPrincipal(principal); - securityUser.setSessionId(claims.get(SESSION_ID, String.class)); + if (claims.get(SESSION_ID, String.class) != null) { + securityUser.setSessionId(claims.get(SESSION_ID, String.class)); + } return securityUser; } diff --git a/application/src/test/java/org/thingsboard/server/service/security/auth/TokenOutdatingTest.java b/application/src/test/java/org/thingsboard/server/service/security/auth/TokenOutdatingTest.java index 187b77fd75..52371e1755 100644 --- a/application/src/test/java/org/thingsboard/server/service/security/auth/TokenOutdatingTest.java +++ b/application/src/test/java/org/thingsboard/server/service/security/auth/TokenOutdatingTest.java @@ -33,6 +33,8 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.event.UserAuthDataChangedEvent; +import org.thingsboard.server.common.data.security.event.UserCredentialsInvalidationEvent; +import org.thingsboard.server.common.data.security.event.UserSessionInvalidationEvent; import org.thingsboard.server.common.data.security.model.JwtToken; import org.thingsboard.server.dao.customer.CustomerService; import org.thingsboard.server.dao.service.DaoSqlTest; @@ -106,7 +108,7 @@ public class TokenOutdatingTest { JwtToken jwtToken = tokenFactory.createAccessJwtToken(securityUser); SECONDS.sleep(1); // need to wait before outdating so that outdatage time is strictly after token issue time - tokenOutdatingService.onUserAuthDataChanged(new UserAuthDataChangedEvent(securityUser.getId(), securityUser.getSessionId(), false)); + tokenOutdatingService.onUserAuthDataChanged(new UserCredentialsInvalidationEvent(securityUser.getId())); assertTrue(tokenOutdatingService.isOutdated(jwtToken, securityUser.getId())); SECONDS.sleep(1); @@ -124,7 +126,7 @@ public class TokenOutdatingTest { }); SECONDS.sleep(1); - tokenOutdatingService.onUserAuthDataChanged(new UserAuthDataChangedEvent(securityUser.getId(), securityUser.getSessionId(), false)); + tokenOutdatingService.onUserAuthDataChanged(new UserCredentialsInvalidationEvent(securityUser.getId())); assertThrows(JwtExpiredTokenException.class, () -> { accessTokenAuthenticationProvider.authenticate(new JwtAuthenticationToken(accessJwtToken)); @@ -140,7 +142,7 @@ public class TokenOutdatingTest { }); SECONDS.sleep(1); - tokenOutdatingService.onUserAuthDataChanged(new UserAuthDataChangedEvent(securityUser.getId(), securityUser.getSessionId(), false)); + tokenOutdatingService.onUserAuthDataChanged(new UserCredentialsInvalidationEvent(securityUser.getId())); assertThrows(CredentialsExpiredException.class, () -> { refreshTokenAuthenticationProvider.authenticate(new RefreshAuthenticationToken(refreshJwtToken)); @@ -152,7 +154,7 @@ public class TokenOutdatingTest { JwtToken jwtToken = tokenFactory.createAccessJwtToken(securityUser); SECONDS.sleep(1); - tokenOutdatingService.onUserAuthDataChanged(new UserAuthDataChangedEvent(securityUser.getId(), securityUser.getSessionId(), false)); + tokenOutdatingService.onUserAuthDataChanged(new UserCredentialsInvalidationEvent(securityUser.getId())); SECONDS.sleep(1); @@ -175,7 +177,8 @@ public class TokenOutdatingTest { }); SECONDS.sleep(1); - tokenOutdatingService.onUserAuthDataChanged(new UserAuthDataChangedEvent(securityUser.getId(), securityUser.getSessionId(), false)); + + tokenOutdatingService.onUserAuthDataChanged(new UserSessionInvalidationEvent(securityUser.getSessionId())); assertThrows(JwtExpiredTokenException.class, () -> { accessTokenAuthenticationProvider.authenticate(new JwtAuthenticationToken(getRawJwtToken(jwtToken))); @@ -186,6 +189,34 @@ public class TokenOutdatingTest { }); } + @Test + public void testResetAllSessions() throws InterruptedException { + JwtToken jwtToken = tokenFactory.createAccessJwtToken(securityUser); + + SecurityUser anotherSecurityUser = new SecurityUser(securityUser, securityUser.isEnabled(), securityUser.getUserPrincipal()); + JwtToken anotherJwtToken = tokenFactory.createAccessJwtToken(anotherSecurityUser); + + assertDoesNotThrow(() -> { + accessTokenAuthenticationProvider.authenticate(new JwtAuthenticationToken(getRawJwtToken(jwtToken))); + }); + + assertDoesNotThrow(() -> { + accessTokenAuthenticationProvider.authenticate(new JwtAuthenticationToken(getRawJwtToken(anotherJwtToken))); + }); + + SECONDS.sleep(1); + + tokenOutdatingService.onUserAuthDataChanged(new UserCredentialsInvalidationEvent(securityUser.getId())); + + assertThrows(JwtExpiredTokenException.class, () -> { + accessTokenAuthenticationProvider.authenticate(new JwtAuthenticationToken(getRawJwtToken(jwtToken))); + }); + + assertThrows(JwtExpiredTokenException.class, () -> { + accessTokenAuthenticationProvider.authenticate(new JwtAuthenticationToken(getRawJwtToken(anotherJwtToken))); + }); + } + private RawAccessJwtToken getRawJwtToken(JwtToken token) { return new RawAccessJwtToken(token.getToken()); diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UserUpdateTimeRedisCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UserUpdateTimeRedisCache.java index 3d96d4c2a7..c4084773a2 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UserUpdateTimeRedisCache.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UserUpdateTimeRedisCache.java @@ -24,13 +24,10 @@ import org.thingsboard.server.cache.RedisTbTransactionalCache; import org.thingsboard.server.cache.TBRedisCacheConfiguration; import org.thingsboard.server.cache.TbFSTRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; -import org.thingsboard.server.common.data.id.UserId; - -import java.util.HashMap; @ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis") @Service("UsersUpdateTimeCache") -public class UserUpdateTimeRedisCache extends RedisTbTransactionalCache> { +public class UserUpdateTimeRedisCache extends RedisTbTransactionalCache { @Autowired public UserUpdateTimeRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UsersUpdateTimeCacheEvictEvent.java b/common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UsersUpdateTimeCacheEvictEvent.java index 16173e388f..1b3d980212 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UsersUpdateTimeCacheEvictEvent.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UsersUpdateTimeCacheEvictEvent.java @@ -16,10 +16,8 @@ package org.thingsboard.server.cache.usersUpdateTime; import lombok.Data; -import org.thingsboard.server.common.data.id.UserId; @Data public class UsersUpdateTimeCacheEvictEvent { - private final UserId userId; - private final String sessionId; + private final String key; } diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UsersUpdateTimeCaffeineCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UsersUpdateTimeCaffeineCache.java index adb2117368..a2c07ecaf0 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UsersUpdateTimeCaffeineCache.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UsersUpdateTimeCaffeineCache.java @@ -21,14 +21,11 @@ import org.springframework.cache.CacheManager; import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CaffeineTbTransactionalCache; import org.thingsboard.server.common.data.CacheConstants; -import org.thingsboard.server.common.data.id.UserId; - -import java.util.HashMap; @ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "caffeine", matchIfMissing = true) @Service("UsersUpdateTimeCache") -public class UsersUpdateTimeCaffeineCache extends CaffeineTbTransactionalCache> { +public class UsersUpdateTimeCaffeineCache extends CaffeineTbTransactionalCache { @Autowired public UsersUpdateTimeCaffeineCache(CacheManager cacheManager) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/event/UserAuthDataChangedEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/event/UserAuthDataChangedEvent.java index 5d9ef3a1cd..9ceaa2386e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/event/UserAuthDataChangedEvent.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/event/UserAuthDataChangedEvent.java @@ -20,18 +20,7 @@ import org.thingsboard.server.common.data.id.UserId; import java.io.Serializable; -@Data -public class UserAuthDataChangedEvent implements Serializable { - private final UserId userId; - private final String sessionId; - private final long ts; - private final boolean dropAllSessions; - - public UserAuthDataChangedEvent(UserId userId, String sessionId, boolean dropAllSessions) { - this.userId = userId; - this.sessionId = sessionId; - this.dropAllSessions = dropAllSessions; - this.ts = System.currentTimeMillis(); - } - +public abstract class UserAuthDataChangedEvent implements Serializable { + public abstract String getId(); + public abstract long getTs(); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/event/UserCredentialsInvalidationEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/event/UserCredentialsInvalidationEvent.java new file mode 100644 index 0000000000..26eac46fc9 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/event/UserCredentialsInvalidationEvent.java @@ -0,0 +1,42 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.security.event; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import org.thingsboard.server.common.data.id.UserId; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class UserCredentialsInvalidationEvent extends UserAuthDataChangedEvent { + private final UserId userId; + private final long ts; + + public UserCredentialsInvalidationEvent(UserId userId) { + this.userId = userId; + this.ts = System.currentTimeMillis(); + } + + @Override + public String getId() { + return userId.toString(); + } + + @Override + public long getTs() { + return ts; + } +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/event/UserSessionInvalidationEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/event/UserSessionInvalidationEvent.java new file mode 100644 index 0000000000..2e6aea6bb9 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/event/UserSessionInvalidationEvent.java @@ -0,0 +1,39 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.security.event; + +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +public class UserSessionInvalidationEvent extends UserAuthDataChangedEvent { + private final String sessionId; + private final long ts; + + public UserSessionInvalidationEvent(String sessionId) { + this.sessionId = sessionId; + this.ts = System.currentTimeMillis(); + } + + @Override + public String getId() { + return sessionId; + } + + @Override + public long getTs() { + return ts; + } +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java index 78ad93b68c..42aac0f59e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java @@ -38,6 +38,7 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.event.UserAuthDataChangedEvent; +import org.thingsboard.server.common.data.security.event.UserCredentialsInvalidationEvent; import org.thingsboard.server.dao.entity.AbstractEntityService; import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.service.DataValidator; @@ -211,7 +212,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic userAuthSettingsDao.removeByUserId(userId); deleteEntityRelations(tenantId, userId); userDao.removeById(tenantId, userId.getId()); - eventPublisher.publishEvent(new UserAuthDataChangedEvent(userId, null, true)); + eventPublisher.publishEvent(new UserCredentialsInvalidationEvent(userId)); } @Override