From f5701691fb22d9f07c85c0ce2095ef2df89acc41 Mon Sep 17 00:00:00 2001 From: johnniang Date: Mon, 29 Apr 2019 18:19:40 +0800 Subject: [PATCH] Complete refresh token logic --- .../halo/app/config/HaloConfiguration.java | 8 +-- .../controller/admin/api/AdminController.java | 7 ++ .../run/halo/app/service/AdminService.java | 9 +++ .../app/service/impl/AdminServiceImpl.java | 65 ++++++++++++++----- 4 files changed, 70 insertions(+), 19 deletions(-) diff --git a/src/main/java/run/halo/app/config/HaloConfiguration.java b/src/main/java/run/halo/app/config/HaloConfiguration.java index a76026ca..471a6670 100644 --- a/src/main/java/run/halo/app/config/HaloConfiguration.java +++ b/src/main/java/run/halo/app/config/HaloConfiguration.java @@ -101,11 +101,10 @@ public class HaloConfiguration { // Set failure handler apiFilter.setFailureHandler(failureHandler); - apiFilter.addExcludeUrlPatterns("/api/admin/*"); FilterRegistrationBean authenticationFilter = new FilterRegistrationBean<>(); authenticationFilter.setFilter(apiFilter); - authenticationFilter.addUrlPatterns("/api/*"); + authenticationFilter.addUrlPatterns("/api/content/*"); authenticationFilter.setOrder(0); return authenticationFilter; } @@ -125,17 +124,18 @@ public class HaloConfiguration { // Config the admin filter adminAuthenticationFilter.addExcludeUrlPatterns( "/api/admin/login", + "/api/admin/refresh/*", "/api/admin/installations", "/api/admin/recoveries/migrations/*" ); adminAuthenticationFilter.addTryAuthUrlMethodPattern("/api/admin/comments", HttpMethod.POST.name()); - adminAuthenticationFilter.addTryAuthUrlMethodPattern("/api/comments", HttpMethod.POST.name()); + adminAuthenticationFilter.addTryAuthUrlMethodPattern("/api/content/comments", HttpMethod.POST.name()); adminAuthenticationFilter.setFailureHandler( failureHandler); FilterRegistrationBean authenticationFilter = new FilterRegistrationBean<>(); authenticationFilter.setFilter(adminAuthenticationFilter); - authenticationFilter.addUrlPatterns("/api/admin/*", "/api/comments"); + authenticationFilter.addUrlPatterns("/api/admin/*", "/api/content/comments"); authenticationFilter.setOrder(1); return authenticationFilter; } diff --git a/src/main/java/run/halo/app/controller/admin/api/AdminController.java b/src/main/java/run/halo/app/controller/admin/api/AdminController.java index f9b1e326..2edb67a1 100644 --- a/src/main/java/run/halo/app/controller/admin/api/AdminController.java +++ b/src/main/java/run/halo/app/controller/admin/api/AdminController.java @@ -52,4 +52,11 @@ public class AdminController { public void logout() { adminService.clearToken(); } + + @PostMapping("refresh/{refreshToken}") + @ApiOperation("Refreshes token") + @CacheLock + public AuthToken refresh(@PathVariable("refreshToken") String refreshToken) { + return adminService.refreshToken(refreshToken); + } } diff --git a/src/main/java/run/halo/app/service/AdminService.java b/src/main/java/run/halo/app/service/AdminService.java index c4321db8..c65aa82b 100644 --- a/src/main/java/run/halo/app/service/AdminService.java +++ b/src/main/java/run/halo/app/service/AdminService.java @@ -45,4 +45,13 @@ public interface AdminService { */ @NonNull StatisticDTO getCount(); + + /** + * Refreshes token. + * + * @param refreshToken refresh token must not be blank + * @return authentication token + */ + @NonNull + AuthToken refreshToken(@NonNull String refreshToken); } diff --git a/src/main/java/run/halo/app/service/impl/AdminServiceImpl.java b/src/main/java/run/halo/app/service/impl/AdminServiceImpl.java index fe7eb510..cd0bf3cd 100644 --- a/src/main/java/run/halo/app/service/impl/AdminServiceImpl.java +++ b/src/main/java/run/halo/app/service/impl/AdminServiceImpl.java @@ -2,6 +2,7 @@ package run.halo.app.service.impl; import cn.hutool.core.lang.Validator; import lombok.extern.slf4j.Slf4j; +import org.springframework.lang.NonNull; import org.springframework.stereotype.Service; import org.springframework.util.Assert; import run.halo.app.cache.StringCacheStore; @@ -93,21 +94,7 @@ public class AdminServiceImpl implements AdminService { } // Generate new token - AuthToken token = new AuthToken(); - - token.setAccessToken(HaloUtils.randomUUIDWithoutDash()); - token.setExpiredIn(ACCESS_TOKEN_EXPIRED_SECONDS); - token.setRefreshToken(HaloUtils.randomUUIDWithoutDash()); - - // Cache those tokens, just for clearing - cacheStore.putAny(SecurityUtils.buildAccessTokenKey(user), token.getAccessToken(), REFRESH_TOKEN_EXPIRED_DAYS, TimeUnit.DAYS); - cacheStore.putAny(SecurityUtils.buildRefreshTokenKey(user), token.getRefreshToken(), REFRESH_TOKEN_EXPIRED_DAYS, TimeUnit.DAYS); - - // Cache those tokens with user id - cacheStore.putAny(SecurityUtils.buildTokenAccessKey(token.getAccessToken()), user.getId(), ACCESS_TOKEN_EXPIRED_SECONDS, TimeUnit.SECONDS); - cacheStore.putAny(SecurityUtils.buildTokenRefreshKey(token.getRefreshToken()), user.getId(), REFRESH_TOKEN_EXPIRED_DAYS, TimeUnit.DAYS); - - return token; + return buildAuthToken(user); } @Override @@ -162,4 +149,52 @@ public class AdminServiceImpl implements AdminService { return statisticDTO; } + @Override + public AuthToken refreshToken(String refreshToken) { + Assert.hasText(refreshToken, "Refresh token must not be blank"); + + Integer userId = cacheStore.getAny(SecurityUtils.buildTokenRefreshKey(refreshToken), Integer.class) + .orElseThrow(() -> new BadRequestException("The refresh token may have been expired already")); + + // Get user info + User user = userService.getById(userId); + + // Remove all token + cacheStore.getAny(SecurityUtils.buildAccessTokenKey(user), String.class).ifPresent(accessToken -> { + cacheStore.delete(SecurityUtils.buildTokenAccessKey(accessToken)); + }); + cacheStore.delete(SecurityUtils.buildTokenRefreshKey(refreshToken)); + cacheStore.delete(SecurityUtils.buildAccessTokenKey(user)); + cacheStore.delete(SecurityUtils.buildRefreshTokenKey(user)); + + return buildAuthToken(user); + } + + /** + * Builds authentication token. + * + * @param user user info must not be null + * @return authentication token + */ + @NonNull + private AuthToken buildAuthToken(@NonNull User user) { + Assert.notNull(user, "User must not be null"); + + // Generate new token + AuthToken token = new AuthToken(); + + token.setAccessToken(HaloUtils.randomUUIDWithoutDash()); + token.setExpiredIn(ACCESS_TOKEN_EXPIRED_SECONDS); + token.setRefreshToken(HaloUtils.randomUUIDWithoutDash()); + + // Cache those tokens, just for clearing + cacheStore.putAny(SecurityUtils.buildAccessTokenKey(user), token.getAccessToken(), REFRESH_TOKEN_EXPIRED_DAYS, TimeUnit.DAYS); + cacheStore.putAny(SecurityUtils.buildRefreshTokenKey(user), token.getRefreshToken(), REFRESH_TOKEN_EXPIRED_DAYS, TimeUnit.DAYS); + + // Cache those tokens with user id + cacheStore.putAny(SecurityUtils.buildTokenAccessKey(token.getAccessToken()), user.getId(), ACCESS_TOKEN_EXPIRED_SECONDS, TimeUnit.SECONDS); + cacheStore.putAny(SecurityUtils.buildTokenRefreshKey(token.getRefreshToken()), user.getId(), REFRESH_TOKEN_EXPIRED_DAYS, TimeUnit.DAYS); + + return token; + } } -- GitLab