From 4fad5879404d3b2f56bc831c4d65fc79faf3010d Mon Sep 17 00:00:00 2001 From: oyurov Date: Thu, 3 Nov 2022 16:52:15 +0100 Subject: [PATCH] Refactoring --- .../auth/DefaultTokenOutdatingService.java | 65 +++++++++++++++++++ .../security/auth/TokenOutdatingService.java | 40 +----------- .../auth/jwt/JwtAuthenticationProvider.java | 2 +- .../RefreshTokenAuthenticationProvider.java | 2 +- .../UserCredentialsInvalidationEvent.java | 2 - 5 files changed, 70 insertions(+), 41 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/service/security/auth/DefaultTokenOutdatingService.java diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/DefaultTokenOutdatingService.java b/application/src/main/java/org/thingsboard/server/service/security/auth/DefaultTokenOutdatingService.java new file mode 100644 index 0000000000..fecc17d33b --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/DefaultTokenOutdatingService.java @@ -0,0 +1,65 @@ +/** + * 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.service.security.auth; + +import io.jsonwebtoken.Claims; +import lombok.RequiredArgsConstructor; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Service; +import org.thingsboard.server.cache.TbTransactionalCache; +import org.thingsboard.server.common.data.StringUtils; +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.service.security.model.token.JwtTokenFactory; + +import java.util.Optional; + +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +@Service +@RequiredArgsConstructor +public class DefaultTokenOutdatingService implements TokenOutdatingService { + private final TbTransactionalCache cache; + private final JwtTokenFactory tokenFactory; + + @EventListener(classes = UserAuthDataChangedEvent.class) + public void onUserAuthDataChanged(UserAuthDataChangedEvent event) { + if (StringUtils.hasText(event.getId())) { + cache.put(event.getId(), event.getTs()); + } + } + + @Override + public boolean isOutdated(JwtToken token, UserId userId) { + Claims claims = tokenFactory.parseTokenClaims(token).getBody(); + long issueTime = claims.getIssuedAt().getTime(); + String sessionId = claims.get("sessionId", String.class); + if (sessionId == null) { + return isTokenOutdated(issueTime, userId.toString()); + } else { + return isTokenOutdated(issueTime, userId.toString()) || isTokenOutdated(issueTime, sessionId); + } + } + + private Boolean isTokenOutdated(long issueTime, String sessionId) { + return Optional.ofNullable(cache.get(sessionId)).map(outdatageTime -> isTokenOutdated(issueTime, outdatageTime.get())).orElse(false); + } + + private boolean isTokenOutdated(long issueTime, Long outdatageTime) { + return MILLISECONDS.toSeconds(issueTime) < MILLISECONDS.toSeconds(outdatageTime); + } +} 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 101455f68e..9013a85553 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 @@ -15,46 +15,12 @@ */ package org.thingsboard.server.service.security.auth; -import io.jsonwebtoken.Claims; -import lombok.RequiredArgsConstructor; -import org.springframework.context.event.EventListener; -import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; -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.service.security.model.token.JwtTokenFactory; -import java.util.Optional; +public interface TokenOutdatingService { + void onUserAuthDataChanged(UserAuthDataChangedEvent event); -import static java.util.concurrent.TimeUnit.MILLISECONDS; - -@Service -@RequiredArgsConstructor -public class TokenOutdatingService { - private final TbTransactionalCache cache; - private final JwtTokenFactory tokenFactory; - - @EventListener(classes = UserAuthDataChangedEvent.class) - public void onUserAuthDataChanged(UserAuthDataChangedEvent event) { - if (StringUtils.hasText(event.getId())) { - cache.put(event.getId(), event.getTs()); - } - } - - public boolean isOutdated(JwtToken token, UserId userId) { - Claims claims = tokenFactory.parseTokenClaims(token).getBody(); - long issueTime = claims.getIssuedAt().getTime(); - String sessionId = claims.get("sessionId", String.class) == null ? "" : claims.get("sessionId", String.class); - return isTokenOutdated(issueTime, userId.toString()) || isTokenOutdated(issueTime, sessionId); - } - - private Boolean isTokenOutdated(long issueTime, String sessionId) { - return Optional.ofNullable(cache.get(sessionId)).map(outdatageTime -> isTokenOutdated(issueTime, outdatageTime.get())).orElse(false); - } - - private boolean isTokenOutdated(long issueTime, Long outdatageTime) { - return MILLISECONDS.toSeconds(issueTime) < MILLISECONDS.toSeconds(outdatageTime); - } + boolean isOutdated(JwtToken token, UserId userId); } diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/JwtAuthenticationProvider.java b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/JwtAuthenticationProvider.java index dcdce946e0..9ce2ae75fc 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/JwtAuthenticationProvider.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/JwtAuthenticationProvider.java @@ -20,8 +20,8 @@ import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.stereotype.Component; -import org.thingsboard.server.service.security.auth.TokenOutdatingService; import org.thingsboard.server.service.security.auth.JwtAuthenticationToken; +import org.thingsboard.server.service.security.auth.TokenOutdatingService; import org.thingsboard.server.service.security.exception.JwtExpiredTokenException; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.token.JwtTokenFactory; 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 700bbd7f74..27549752e4 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 @@ -33,11 +33,11 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.security.Authority; -import org.thingsboard.server.service.security.auth.TokenOutdatingService; import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.dao.customer.CustomerService; import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.service.security.auth.RefreshAuthenticationToken; +import org.thingsboard.server.service.security.auth.TokenOutdatingService; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.UserPrincipal; import org.thingsboard.server.service.security.model.token.JwtTokenFactory; 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 index 26eac46fc9..63ee49e53b 100644 --- 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 @@ -16,10 +16,8 @@ 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;