Procházet zdrojové kódy

框架新增刷新token接口

mac před 2 roky
rodič
revize
7abc9694c5

+ 2 - 0
kxs-common/kxs-common-security/src/main/java/com/kxs/common/security/component/SkyResourceServerConfiguration.java

@@ -9,6 +9,7 @@ import com.kxs.common.security.support.handler.SkyAuthenticationFailureEventHand
 import com.kxs.common.security.support.handler.SkyAuthenticationSuccessEventHandler;
 import com.kxs.common.security.support.password.OAuth2ResourceOwnerPasswordAuthenticationConverter;
 import com.kxs.common.security.support.password.OAuth2ResourceOwnerPasswordAuthenticationProvider;
+import com.kxs.common.security.support.refresh.OAuth2ResourceOwnerRefreshAuthenticationConverter;
 import com.kxs.common.security.support.sms.OAuth2ResourceOwnerSmsAuthenticationConverter;
 import com.kxs.common.security.support.sms.OAuth2ResourceOwnerSmsAuthenticationProvider;
 import lombok.RequiredArgsConstructor;
@@ -122,6 +123,7 @@ public class SkyResourceServerConfiguration {
 	private AuthenticationConverter accessTokenRequestConverter() {
 		return new DelegatingAuthenticationConverter(Arrays.asList(
 				new OAuth2ResourceOwnerPasswordAuthenticationConverter(),
+				new OAuth2ResourceOwnerRefreshAuthenticationConverter(),
 				new OAuth2ResourceOwnerSmsAuthenticationConverter(), new OAuth2RefreshTokenAuthenticationConverter(),
 				new OAuth2ClientCredentialsAuthenticationConverter(),
 				new OAuth2AuthorizationCodeAuthenticationConverter(),

+ 59 - 0
kxs-common/kxs-common-security/src/main/java/com/kxs/common/security/support/refresh/OAuth2ResourceOwnerRefreshAuthenticationConverter.java

@@ -0,0 +1,59 @@
+package com.kxs.common.security.support.refresh;
+
+import com.kxs.common.core.constant.SecurityConstants;
+import com.kxs.common.security.util.OAuth2EndpointUtils;
+import jakarta.servlet.http.HttpServletRequest;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.oauth2.core.AuthorizationGrantType;
+import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
+import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
+import org.springframework.security.oauth2.server.authorization.authentication.OAuth2RefreshTokenAuthenticationToken;
+import org.springframework.security.web.authentication.AuthenticationConverter;
+import org.springframework.util.MultiValueMap;
+import org.springframework.util.StringUtils;
+
+import java.util.*;
+
+/**
+ * @author LXQ
+ * @date 2024-06-02
+ *
+ * 刷新token转换器
+ */
+public class OAuth2ResourceOwnerRefreshAuthenticationConverter  implements AuthenticationConverter {
+
+	@Override
+	public Authentication convert(HttpServletRequest request) {
+		String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE);
+		if (!AuthorizationGrantType.REFRESH_TOKEN.getValue().equals(grantType)) {
+			return null;
+		} else {
+			Authentication clientPrincipal = SecurityContextHolder.getContext().getAuthentication();
+			MultiValueMap<String, String> parameters = OAuth2EndpointUtils.getParameters(request);
+			String refreshToken = parameters.getFirst(OAuth2ParameterNames.REFRESH_TOKEN);
+			if (!StringUtils.hasText(refreshToken) || parameters.get(OAuth2ParameterNames.REFRESH_TOKEN).size() != 1) {
+				OAuth2EndpointUtils.throwError(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.REFRESH_TOKEN, OAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI);
+			}
+
+			String scope = parameters.getFirst(OAuth2ParameterNames.SCOPE);
+			if (StringUtils.hasText(scope) && parameters.get(OAuth2ParameterNames.SCOPE).size() != 1) {
+				OAuth2EndpointUtils.throwError(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.SCOPE, OAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI);
+			}
+
+			Set<String> requestedScopes = null;
+			if (StringUtils.hasText(scope)) {
+				requestedScopes = new HashSet<>(Arrays.asList(StringUtils.delimitedListToStringArray(scope, " ")));
+			}
+
+			Map<String, Object> additionalParameters = new HashMap<>();
+			parameters.forEach((key, value) -> {
+				if (!key.equals(OAuth2ParameterNames.GRANT_TYPE) && !key.equals(OAuth2ParameterNames.REFRESH_TOKEN) && !key.equals(OAuth2ParameterNames.SCOPE)) {
+					additionalParameters.put(key, value.size() == 1 ? value.get(0) : value.toArray(new String[0]));
+				}
+
+			});
+			return new OAuth2RefreshTokenAuthenticationToken(refreshToken, clientPrincipal, requestedScopes, additionalParameters);
+		}
+	}
+}

+ 3 - 1
kxs-common/kxs-common-security/src/main/java/com/kxs/common/security/util/OAuth2EndpointUtils.java

@@ -3,6 +3,7 @@ package com.kxs.common.security.util;
 import cn.hutool.core.map.MapUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.google.common.base.CaseFormat;
 import jakarta.servlet.http.HttpServletRequest;
 import lombok.experimental.UtilityClass;
 import org.springframework.security.oauth2.core.OAuth2AccessToken;
@@ -49,7 +50,8 @@ public class OAuth2EndpointUtils {
 			if(body != null && !body.isEmpty()){
                 body.keySet().forEach(key -> {
                     String value = body.get(key).toString();
-                    parameters.add(key, value);
+					//security全是下划线,所以参数需要转下划线
+                    parameters.add(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, key), value);
                 });
 			}
 			//写入登陆名到参数内,方便后续获取