From b6c97c6132928207fc0bdc75eb1168e579198198 Mon Sep 17 00:00:00 2001 From: lbw Date: Tue, 31 May 2022 17:06:23 +0800 Subject: [PATCH] =?UTF-8?q?:recycle:=20Refactoring=20code.=20close=20#I5A4?= =?UTF-8?q?0W=20PigRedisOAuth2AuthorizationService=20=E9=87=8D=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pig/auth/endpoint/PigTokenEndpoint.java | 4 +- .../CustomeOAuth2AccessTokenGenerator.java | 6 +- ...eOwnerPasswordAuthenticationConverter.java | 1 + ...ceOwnerPasswordAuthenticationProvider.java | 1 + ...sourceOwnerSmsAuthenticationConverter.java | 1 + ...esourceOwnerSmsAuthenticationProvider.java | 1 + ...edisOAuth2AuthorizationConsentService.java | 22 ++-- .../PigRedisOAuth2AuthorizationService.java | 118 ++++++++++++------ .../security/util}/OAuth2EndpointUtils.java | 4 +- .../util}/OAuth2ErrorCodesExpand.java | 2 +- 10 files changed, 101 insertions(+), 59 deletions(-) rename {pig-auth/src/main/java/com/pig4cloud/pig/auth/support => pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/util}/OAuth2EndpointUtils.java (96%) rename {pig-auth/src/main/java/com/pig4cloud/pig/auth/support => pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/util}/OAuth2ErrorCodesExpand.java (93%) diff --git a/pig-auth/src/main/java/com/pig4cloud/pig/auth/endpoint/PigTokenEndpoint.java b/pig-auth/src/main/java/com/pig4cloud/pig/auth/endpoint/PigTokenEndpoint.java index eb8bd3f4..689a5945 100644 --- a/pig-auth/src/main/java/com/pig4cloud/pig/auth/endpoint/PigTokenEndpoint.java +++ b/pig-auth/src/main/java/com/pig4cloud/pig/auth/endpoint/PigTokenEndpoint.java @@ -21,8 +21,8 @@ import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.pig4cloud.pig.admin.api.entity.SysOauthClientDetails; import com.pig4cloud.pig.admin.api.feign.RemoteClientDetailsService; -import com.pig4cloud.pig.auth.support.OAuth2EndpointUtils; -import com.pig4cloud.pig.auth.support.OAuth2ErrorCodesExpand; +import com.pig4cloud.pig.common.security.util.OAuth2EndpointUtils; +import com.pig4cloud.pig.common.security.util.OAuth2ErrorCodesExpand; import com.pig4cloud.pig.common.core.constant.CacheConstants; import com.pig4cloud.pig.common.core.constant.CommonConstants; import com.pig4cloud.pig.common.core.constant.SecurityConstants; diff --git a/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/CustomeOAuth2AccessTokenGenerator.java b/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/CustomeOAuth2AccessTokenGenerator.java index 92985066..6a1cdc5c 100644 --- a/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/CustomeOAuth2AccessTokenGenerator.java +++ b/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/CustomeOAuth2AccessTokenGenerator.java @@ -1,6 +1,5 @@ package com.pig4cloud.pig.auth.support; -import com.pig4cloud.pig.common.core.constant.SecurityConstants; import org.springframework.lang.Nullable; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.oauth2.core.ClaimAccessor; @@ -86,9 +85,8 @@ public class CustomeOAuth2AccessTokenGenerator implements OAuth2TokenGenerator redisTemplate; + private final RedisTemplate redisTemplate; + + private final static Long TIMEOUT = 10L; @Override public void save(OAuth2AuthorizationConsent authorizationConsent) { Assert.notNull(authorizationConsent, "authorizationConsent cannot be null"); - redisTemplate.opsForHash().put(buildKey(authorizationConsent), authorizationConsent.getRegisteredClientId(), authorizationConsent); + + redisTemplate.opsForValue().set(buildKey(authorizationConsent), authorizationConsent, TIMEOUT, + TimeUnit.MINUTES); + } @Override public void remove(OAuth2AuthorizationConsent authorizationConsent) { Assert.notNull(authorizationConsent, "authorizationConsent cannot be null"); - redisTemplate.opsForHash().delete(buildKey(authorizationConsent), authorizationConsent.getRegisteredClientId()); + redisTemplate.delete(buildKey(authorizationConsent)); } @Override public OAuth2AuthorizationConsent findById(String registeredClientId, String principalName) { Assert.hasText(registeredClientId, "registeredClientId cannot be empty"); Assert.hasText(principalName, "principalName cannot be empty"); - return (OAuth2AuthorizationConsent) redisTemplate.opsForHash().get(buildKey(registeredClientId, principalName), registeredClientId); + return (OAuth2AuthorizationConsent) redisTemplate.opsForValue() + .get(buildKey(registeredClientId, principalName)); } - private static String buildKey(String registeredClientId, String principalName) { - return "OAC::" + registeredClientId + "::" + principalName; + return "token:consent:" + registeredClientId + ":" + principalName; } private static String buildKey(OAuth2AuthorizationConsent authorizationConsent) { return buildKey(authorizationConsent.getRegisteredClientId(), authorizationConsent.getPrincipalName()); } - } - - diff --git a/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/service/PigRedisOAuth2AuthorizationService.java b/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/service/PigRedisOAuth2AuthorizationService.java index 7e969236..9818e930 100644 --- a/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/service/PigRedisOAuth2AuthorizationService.java +++ b/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/service/PigRedisOAuth2AuthorizationService.java @@ -7,10 +7,17 @@ import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.OAuth2AuthorizationCode; import org.springframework.security.oauth2.core.OAuth2RefreshToken; import org.springframework.security.oauth2.core.OAuth2TokenType; +import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.util.Assert; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + /** * @author lengleng * @date 2022/5/27 @@ -18,81 +25,110 @@ import org.springframework.util.Assert; @RequiredArgsConstructor public class PigRedisOAuth2AuthorizationService implements OAuth2AuthorizationService { + private final static Long TIMEOUT = 10L; + private static final String AUTHORIZATION = "token"; - private final RedisTemplate redisTemplate; + private final RedisTemplate redisTemplate; @Override public void save(OAuth2Authorization authorization) { Assert.notNull(authorization, "authorization cannot be null"); - redisTemplate.opsForHash().put(AUTHORIZATION, authorization.getId(), authorization); + + if (isState(authorization)) { + String token = authorization.getAttribute("state"); + redisTemplate.opsForValue().set(buildKey(OAuth2ParameterNames.STATE, token), authorization, TIMEOUT, + TimeUnit.MINUTES); + } + + if (isCode(authorization)) { + OAuth2Authorization.Token authorizationCode = authorization + .getToken(OAuth2AuthorizationCode.class); + OAuth2AuthorizationCode authorizationCodeToken = authorizationCode.getToken(); + long between = ChronoUnit.MINUTES.between(authorizationCodeToken.getIssuedAt(), + authorizationCodeToken.getExpiresAt()); + redisTemplate.opsForValue().set(buildKey(OAuth2ParameterNames.CODE, authorizationCodeToken.getTokenValue()), + authorization, between, TimeUnit.MINUTES); + } + + if (isRefreshToken(authorization)) { + OAuth2RefreshToken refreshToken = authorization.getRefreshToken().getToken(); + long between = ChronoUnit.SECONDS.between(refreshToken.getIssuedAt(), refreshToken.getExpiresAt()); + redisTemplate.opsForValue().set(buildKey(OAuth2ParameterNames.REFRESH_TOKEN, refreshToken.getTokenValue()), + authorization, between, TimeUnit.SECONDS); + } + + if (isAccessToken(authorization)) { + OAuth2AccessToken accessToken = authorization.getAccessToken().getToken(); + long between = ChronoUnit.SECONDS.between(accessToken.getIssuedAt(), accessToken.getExpiresAt()); + redisTemplate.opsForValue().set(buildKey(OAuth2ParameterNames.ACCESS_TOKEN, accessToken.getTokenValue()), + authorization, between, TimeUnit.SECONDS); + } } @Override public void remove(OAuth2Authorization authorization) { Assert.notNull(authorization, "authorization cannot be null"); - redisTemplate.opsForHash().delete(AUTHORIZATION, authorization.getId()); + + List keys = new ArrayList<>(); + if (isState(authorization)) { + String token = authorization.getAttribute("state"); + keys.add(buildKey(OAuth2ParameterNames.STATE, token)); + } + + if (isCode(authorization)) { + OAuth2Authorization.Token authorizationCode = authorization + .getToken(OAuth2AuthorizationCode.class); + OAuth2AuthorizationCode authorizationCodeToken = authorizationCode.getToken(); + keys.add(buildKey(OAuth2ParameterNames.CODE, authorizationCodeToken.getTokenValue())); + } + + if (isRefreshToken(authorization)) { + OAuth2RefreshToken refreshToken = authorization.getRefreshToken().getToken(); + keys.add(buildKey(OAuth2ParameterNames.REFRESH_TOKEN, refreshToken.getTokenValue())); + } + + if (isAccessToken(authorization)) { + OAuth2AccessToken accessToken = authorization.getAccessToken().getToken(); + keys.add(buildKey(OAuth2ParameterNames.ACCESS_TOKEN, accessToken.getTokenValue())); + } + redisTemplate.delete(keys); } @Override @Nullable public OAuth2Authorization findById(String id) { - Assert.hasText(id, "id cannot be empty"); - return (OAuth2Authorization) redisTemplate.opsForHash().get(AUTHORIZATION, id); + throw new UnsupportedOperationException(); } @Override @Nullable public OAuth2Authorization findByToken(String token, @Nullable OAuth2TokenType tokenType) { Assert.hasText(token, "token cannot be empty"); - for (Object authorization : redisTemplate.opsForHash().values(AUTHORIZATION)) { - if (hasToken((OAuth2Authorization) authorization, token, tokenType)) { - return (OAuth2Authorization) authorization; - } - } - return null; + Assert.notNull(tokenType, "tokenType cannot be empty"); + return (OAuth2Authorization) redisTemplate.opsForValue().get(buildKey(tokenType.getValue(), token)); } - private static boolean hasToken(OAuth2Authorization authorization, String token, - @Nullable OAuth2TokenType tokenType) { - if (tokenType != null) { - if ("state".equals(tokenType.getValue())) { - return matchesState(authorization, token); - } - else if ("code".equals(tokenType.getValue())) { - return matchesAuthorizationCode(authorization, token); - } - else if (OAuth2TokenType.ACCESS_TOKEN.equals(tokenType)) { - return matchesAccessToken(authorization, token); - } - else { - return OAuth2TokenType.REFRESH_TOKEN.equals(tokenType) && matchesRefreshToken(authorization, token); - } - } - else { - return matchesState(authorization, token) || matchesAuthorizationCode(authorization, token) - || matchesAccessToken(authorization, token) || matchesRefreshToken(authorization, token); - } + private String buildKey(String type, String id) { + return String.format("%s::%s::%s", AUTHORIZATION, type, id); } - private static boolean matchesState(OAuth2Authorization authorization, String token) { - return token.equals(authorization.getAttribute("state")); + private static boolean isState(OAuth2Authorization authorization) { + return Objects.nonNull(authorization.getAttribute("state")); } - private static boolean matchesAuthorizationCode(OAuth2Authorization authorization, String token) { + private static boolean isCode(OAuth2Authorization authorization) { OAuth2Authorization.Token authorizationCode = authorization .getToken(OAuth2AuthorizationCode.class); - return authorizationCode != null && authorizationCode.getToken().getTokenValue().equals(token); + return Objects.nonNull(authorizationCode); } - private static boolean matchesAccessToken(OAuth2Authorization authorization, String token) { - OAuth2Authorization.Token accessToken = authorization.getToken(OAuth2AccessToken.class); - return accessToken != null && accessToken.getToken().getTokenValue().equals(token); + private static boolean isRefreshToken(OAuth2Authorization authorization) { + return Objects.nonNull(authorization.getRefreshToken()); } - private static boolean matchesRefreshToken(OAuth2Authorization authorization, String token) { - OAuth2Authorization.Token refreshToken = authorization.getToken(OAuth2RefreshToken.class); - return refreshToken != null && refreshToken.getToken().getTokenValue().equals(token); + private static boolean isAccessToken(OAuth2Authorization authorization) { + return Objects.nonNull(authorization.getAccessToken()); } } diff --git a/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/OAuth2EndpointUtils.java b/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/util/OAuth2EndpointUtils.java similarity index 96% rename from pig-auth/src/main/java/com/pig4cloud/pig/auth/support/OAuth2EndpointUtils.java rename to pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/util/OAuth2EndpointUtils.java index 1fe5fcb8..567f062a 100644 --- a/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/OAuth2EndpointUtils.java +++ b/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/util/OAuth2EndpointUtils.java @@ -1,4 +1,4 @@ -package com.pig4cloud.pig.auth.support; +package com.pig4cloud.pig.common.security.util; import lombok.experimental.UtilityClass; import org.springframework.security.oauth2.core.*; @@ -21,7 +21,7 @@ import java.util.Map; @UtilityClass public class OAuth2EndpointUtils { - static final String ACCESS_TOKEN_REQUEST_ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2"; + public final String ACCESS_TOKEN_REQUEST_ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2"; public MultiValueMap getParameters(HttpServletRequest request) { Map parameterMap = request.getParameterMap(); diff --git a/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/OAuth2ErrorCodesExpand.java b/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/util/OAuth2ErrorCodesExpand.java similarity index 93% rename from pig-auth/src/main/java/com/pig4cloud/pig/auth/support/OAuth2ErrorCodesExpand.java rename to pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/util/OAuth2ErrorCodesExpand.java index 58a526cf..69882d18 100644 --- a/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/OAuth2ErrorCodesExpand.java +++ b/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/util/OAuth2ErrorCodesExpand.java @@ -1,4 +1,4 @@ -package com.pig4cloud.pig.auth.support; +package com.pig4cloud.pig.common.security.util; /** * @author jumuning