From 2da0ddec6a51de36a2589c70d72c772c205f4ced Mon Sep 17 00:00:00 2001
From: smallbun <2689170096@qq.com>
Date: Sat, 26 Aug 2023 18:11:06 +0800
Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E5=AE=8C=E5=96=84=E6=94=AF?=
=?UTF-8?q?=E4=BB=98=E5=AE=9D=E8=AE=A4=E8=AF=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../alipay/AlipayIdpOAuth2Config.java | 13 ++
.../alipay/client/AlipayClient.java | 195 ++++++++++++++++++
.../AlipaySystemOauthTokenResponse.java | 73 +++++++
.../AlipaySystemUserInfoShareResponse.java | 79 +++++++
.../AlipayAuthenticationConfigurer.java | 30 ++-
.../AlipayAuthenticationConstants.java | 5 +
.../AlipayLoginAuthenticationFilter.java | 109 +++++++++-
.../src/components/IconFont/lib/iconfont.js | 2 +-
.../components/Config/AliPayOauthConfig.tsx | 79 +++++++
.../components/Config/Config.tsx | 8 +-
.../components/Config/GiteeOauthConfig.tsx | 14 +-
.../components/Config/GithubOauthConfig.tsx | 8 +-
.../components/CreateModal/CreateModal.tsx | 12 +-
.../pages/authn/IdentityProvider/constant.ts | 13 +-
.../authn/IdentityProvider/locales/zh-CN.ts | 41 +++-
.../authn/IdentityProviderConverter.java | 5 +-
.../security/IdpRedirectParameterMatcher.java | 6 +-
.../security/PortalSecurityConfiguration.java | 18 +-
.../src/components/IconFont/lib/iconfont.js | 2 +-
.../main/portal-fe/src/constants/index.tsx | 1 +
.../main/portal-fe/src/pages/Login/Login.tsx | 20 ++
21 files changed, 686 insertions(+), 47 deletions(-)
create mode 100644 eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/client/AlipayClient.java
create mode 100644 eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/client/AlipaySystemOauthTokenResponse.java
create mode 100644 eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/client/AlipaySystemUserInfoShareResponse.java
create mode 100644 eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/components/Config/AliPayOauthConfig.tsx
diff --git a/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/AlipayIdpOAuth2Config.java b/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/AlipayIdpOAuth2Config.java
index 1ced91b8..53c9597a 100644
--- a/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/AlipayIdpOAuth2Config.java
+++ b/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/AlipayIdpOAuth2Config.java
@@ -33,10 +33,23 @@ import jakarta.validation.constraints.NotBlank;
@Data
@EqualsAndHashCode(callSuper = true)
public class AlipayIdpOAuth2Config extends IdentityProviderConfig {
+
/**
* 商户ID
*/
@NotBlank(message = "商户ID不能为空")
private String appId;
+ /**
+ * 应用私钥
+ */
+ @NotBlank(message = "应用私钥")
+ private String appPrivateKey;
+
+ /**
+ * 支付宝公钥
+ */
+ @NotBlank(message = "支付宝公钥")
+ private String alipayPublicKey;
+
}
diff --git a/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/client/AlipayClient.java b/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/client/AlipayClient.java
new file mode 100644
index 00000000..c78c602e
--- /dev/null
+++ b/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/client/AlipayClient.java
@@ -0,0 +1,195 @@
+/*
+ * eiam-authentication-alipay - Employee Identity and Access Management
+ * Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package cn.topiam.employee.authentication.alipay.client;
+
+import java.util.Map;
+
+import com.aliyun.tea.*;
+
+/**
+ *
+ * @author TopIAM
+ * Created by support@topiam.cn on 2023/8/25 22:26
+ */
+public class AlipayClient {
+
+ public com.alipay.easysdk.kernel.Client kernel;
+
+ public AlipayClient(com.alipay.easysdk.kernel.Client kernel) {
+ this.kernel = kernel;
+ }
+
+ /**
+ * 获取token
+ *
+ * @param code {@link String}
+ * @return {@link AlipaySystemOauthTokenResponse}
+ * @throws Exception Exception
+ */
+ public AlipaySystemOauthTokenResponse getOauthToken(String code) throws Exception {
+ java.util.Map runtime = getRuntime();
+ TeaRequest request = null;
+ long now = System.currentTimeMillis();
+ int retryTimes = 0;
+ while (Tea.allowRetry((java.util.Map) runtime.get("retry"), retryTimes,
+ now)) {
+ if (retryTimes > 0) {
+ int backoffTime = Tea.getBackoffTime(runtime.get("backoff"), retryTimes);
+ if (backoffTime > 0) {
+ Tea.sleep(backoffTime);
+ }
+ }
+ retryTimes = retryTimes + 1;
+ try {
+ java.util.Map systemParams = TeaConverter.buildMap(
+ new TeaPair("method", "alipay.system.oauth.token"),
+ new TeaPair("app_id", kernel.getConfig("appId")),
+ new TeaPair("timestamp", kernel.getTimestamp()), new TeaPair("format", "json"),
+ new TeaPair("charset", "UTF-8"),
+ new TeaPair("sign_type", kernel.getConfig("signType")),
+ new TeaPair("app_cert_sn", kernel.getMerchantCertSN()),
+ new TeaPair("alipay_root_cert_sn", kernel.getAlipayRootCertSN()));
+ java.util.Map bizParams = new java.util.HashMap<>();
+ java.util.Map textParams = TeaConverter.buildMap(
+ new TeaPair("grant_type", "authorization_code"), new TeaPair("code", code));
+ request = getRequest(systemParams, bizParams, textParams);
+ TeaResponse response = Tea.doAction(request, runtime);
+
+ java.util.Map respMap = kernel.readAsJson(response,
+ "alipay.system.oauth.token");
+ if (kernel.isCertMode()) {
+ if (kernel.verify(respMap,
+ kernel.extractAlipayPublicKey(kernel.getAlipayCertSN(respMap)))) {
+ return TeaModel.toModel(kernel.toRespModel(respMap),
+ new AlipaySystemOauthTokenResponse());
+ }
+
+ } else {
+ if (kernel.verify(respMap, kernel.getConfig("alipayPublicKey"))) {
+ return TeaModel.toModel(kernel.toRespModel(respMap),
+ new AlipaySystemOauthTokenResponse());
+ }
+
+ }
+
+ throw new TeaException(
+ TeaConverter.buildMap(new TeaPair("message", "验签失败,请检查支付宝公钥设置是否正确。")));
+ } catch (Exception e) {
+ if (Tea.isRetryable(e)) {
+ continue;
+ }
+ throw new RuntimeException(e);
+ }
+ }
+
+ throw new TeaUnretryableException(request);
+ }
+
+ /**
+ * 获取用户信息
+ *
+ * @param authToken {@link String}
+ * @return {@link AlipaySystemOauthTokenResponse}
+ * @throws Exception Exception
+ */
+ public AlipaySystemUserInfoShareResponse getUserInfo(String authToken) throws Exception {
+ java.util.Map runtime = getRuntime();
+
+ TeaRequest request = null;
+ long now = System.currentTimeMillis();
+ int retryTimes = 0;
+ while (Tea.allowRetry((java.util.Map) runtime.get("retry"), retryTimes,
+ now)) {
+ if (retryTimes > 0) {
+ int backoffTime = Tea.getBackoffTime(runtime.get("backoff"), retryTimes);
+ if (backoffTime > 0) {
+ Tea.sleep(backoffTime);
+ }
+ }
+ retryTimes = retryTimes + 1;
+ try {
+ java.util.Map systemParams = TeaConverter.buildMap(
+ new TeaPair("method", "alipay.user.info.share"),
+ new TeaPair("app_id", kernel.getConfig("appId")),
+ new TeaPair("timestamp", kernel.getTimestamp()), new TeaPair("format", "json"),
+ new TeaPair("charset", "UTF-8"),
+ new TeaPair("sign_type", kernel.getConfig("signType")),
+ new TeaPair("app_cert_sn", kernel.getMerchantCertSN()),
+ new TeaPair("alipay_root_cert_sn", kernel.getAlipayRootCertSN()));
+ java.util.Map bizParams = new java.util.HashMap<>();
+ java.util.Map textParams = TeaConverter
+ .buildMap(new TeaPair("auth_token", authToken));
+ request = getRequest(systemParams, bizParams, textParams);
+ TeaResponse response = Tea.doAction(request, runtime);
+
+ java.util.Map respMap = kernel.readAsJson(response,
+ "alipay.user.info.share");
+ if (kernel.isCertMode()) {
+ if (kernel.verify(respMap,
+ kernel.extractAlipayPublicKey(kernel.getAlipayCertSN(respMap)))) {
+ return TeaModel.toModel(kernel.toRespModel(respMap),
+ new AlipaySystemUserInfoShareResponse());
+ }
+
+ } else {
+ if (kernel.verify(respMap, kernel.getConfig("alipayPublicKey"))) {
+ return TeaModel.toModel(kernel.toRespModel(respMap),
+ new AlipaySystemUserInfoShareResponse());
+ }
+
+ }
+
+ throw new TeaException(
+ TeaConverter.buildMap(new TeaPair("message", "验签失败,请检查支付宝公钥设置是否正确。")));
+ } catch (Exception e) {
+ if (Tea.isRetryable(e)) {
+ continue;
+ }
+ throw new RuntimeException(e);
+ }
+ }
+
+ throw new TeaUnretryableException(request);
+ }
+
+ private TeaRequest getRequest(Map systemParams, Map bizParams,
+ Map textParams) throws Exception {
+ TeaRequest request = new TeaRequest();
+
+ request.protocol = kernel.getConfig("protocol");
+ request.method = "POST";
+ request.pathname = "/gateway.do";
+ request.headers = TeaConverter.buildMap(
+ new TeaPair("host", kernel.getConfig("gatewayHost")),
+ new TeaPair("content-type", "application/x-www-form-urlencoded;charset=utf-8"));
+ request.query = kernel.sortMap(TeaConverter.merge(
+ String.class, TeaConverter.buildMap(new TeaPair("sign", kernel.sign(systemParams,
+ bizParams, textParams, kernel.getConfig("merchantPrivateKey")))),
+ systemParams, textParams));
+ request.body = Tea.toReadable(kernel.toUrlEncodedRequestBody(bizParams));
+ return request;
+ }
+
+ private java.util.Map getRuntime() throws Exception {
+ return TeaConverter.buildMap(new TeaPair("ignoreSSL", kernel.getConfig("ignoreSSL")),
+ new TeaPair("httpProxy", kernel.getConfig("httpProxy")),
+ new TeaPair("connectTimeout", 15000), new TeaPair("readTimeout", 15000),
+ new TeaPair("retry", TeaConverter.buildMap(new TeaPair("maxAttempts", 0))));
+ }
+
+}
diff --git a/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/client/AlipaySystemOauthTokenResponse.java b/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/client/AlipaySystemOauthTokenResponse.java
new file mode 100644
index 00000000..2c92ad68
--- /dev/null
+++ b/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/client/AlipaySystemOauthTokenResponse.java
@@ -0,0 +1,73 @@
+/*
+ * eiam-authentication-alipay - Employee Identity and Access Management
+ * Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package cn.topiam.employee.authentication.alipay.client;
+
+import com.aliyun.tea.*;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * @author TopIAM
+ * Created by support@topiam.cn on 2023/8/25 22:26
+ */
+@Getter
+@Setter
+public class AlipaySystemOauthTokenResponse extends TeaModel {
+ @NameInMap("http_body")
+ @Validation(required = true)
+ public String httpBody;
+
+ @NameInMap("code")
+ @Validation(required = true)
+ public String code;
+
+ @NameInMap("msg")
+ @Validation(required = true)
+ public String msg;
+
+ @NameInMap("sub_code")
+ @Validation(required = true)
+ public String subCode;
+
+ @NameInMap("sub_msg")
+ @Validation(required = true)
+ public String subMsg;
+
+ @NameInMap("open_id")
+ @Validation(required = true)
+ public String openId;
+
+ @NameInMap("access_token")
+ @Validation(required = true)
+ public String accessToken;
+
+ @NameInMap("expires_in")
+ @Validation(required = true)
+ public Long expiresIn;
+
+ @NameInMap("refresh_token")
+ @Validation(required = true)
+ public String refreshToken;
+
+ @NameInMap("re_expires_in")
+ @Validation(required = true)
+ public Long reExpiresIn;
+
+}
diff --git a/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/client/AlipaySystemUserInfoShareResponse.java b/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/client/AlipaySystemUserInfoShareResponse.java
new file mode 100644
index 00000000..afd83932
--- /dev/null
+++ b/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/client/AlipaySystemUserInfoShareResponse.java
@@ -0,0 +1,79 @@
+/*
+ * eiam-authentication-alipay - Employee Identity and Access Management
+ * Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package cn.topiam.employee.authentication.alipay.client;
+
+import com.aliyun.tea.NameInMap;
+import com.aliyun.tea.TeaModel;
+import com.aliyun.tea.Validation;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * @author TopIAM
+ * Created by support@topiam.cn on 2023/8/25 22:26
+ */
+@Getter
+@Setter
+public class AlipaySystemUserInfoShareResponse extends TeaModel {
+ @NameInMap("http_body")
+ @Validation(required = true)
+ public String httpBody;
+
+ @NameInMap("code")
+ @Validation(required = true)
+ public String code;
+
+ @NameInMap("msg")
+ @Validation(required = true)
+ public String msg;
+
+ @NameInMap("sub_code")
+ @Validation(required = true)
+ public String subCode;
+
+ @NameInMap("sub_msg")
+ @Validation(required = true)
+ public String subMsg;
+
+ @NameInMap("user_id")
+ @Validation(required = true)
+ public String userId;
+
+ @NameInMap("avatar")
+ @Validation(required = true)
+ public String avatar;
+
+ @NameInMap("city")
+ @Validation(required = true)
+ public Long city;
+
+ @NameInMap("nick_name")
+ @Validation(required = true)
+ public String nickName;
+
+ @NameInMap("province")
+ @Validation(required = true)
+ public Long province;
+
+ @NameInMap("gender")
+ @Validation(required = true)
+ public Long gender;
+
+}
diff --git a/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/configurer/AlipayAuthenticationConfigurer.java b/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/configurer/AlipayAuthenticationConfigurer.java
index 61321b51..974c4086 100644
--- a/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/configurer/AlipayAuthenticationConfigurer.java
+++ b/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/configurer/AlipayAuthenticationConfigurer.java
@@ -17,8 +17,11 @@
*/
package cn.topiam.employee.authentication.alipay.configurer;
+import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer;
+import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter;
+import org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
@@ -29,6 +32,10 @@ import cn.topiam.employee.authentication.alipay.filter.AlipayLoginAuthentication
import cn.topiam.employee.authentication.common.service.UserIdpService;
import cn.topiam.employee.common.repository.authentication.IdentityProviderRepository;
+import lombok.NonNull;
+import lombok.Setter;
+import static cn.topiam.employee.support.security.util.HttpSecurityFilterOrderRegistrationUtils.putFilterBefore;
+
/**
* 认证配置
*
@@ -37,6 +44,9 @@ import cn.topiam.employee.common.repository.authentication.IdentityProviderRepos
*/
public class AlipayAuthenticationConfigurer extends
AbstractAuthenticationFilterConfigurer {
+ @Setter
+ @NonNull
+ private String loginProcessingUrl = AlipayLoginAuthenticationFilter.DEFAULT_FILTER_PROCESSES_URI;
private final IdentityProviderRepository identityProviderRepository;
private final UserIdpService userIdpService;
@@ -49,6 +59,24 @@ public class AlipayAuthenticationConfigurer extends
this.userIdpService = userIdpService;
}
+ @Override
+ public void init(HttpSecurity http) throws Exception {
+ //支付宝登录认证
+ this.setAuthenticationFilter(
+ new AlipayLoginAuthenticationFilter(userIdpService, identityProviderRepository));
+ putFilterBefore(http, this.getAuthenticationFilter(),
+ OAuth2LoginAuthenticationFilter.class);
+
+ //支付宝请求重定向
+ http.addFilterBefore(
+ new AlipayAuthorizationRequestRedirectFilter(identityProviderRepository),
+ OAuth2AuthorizationRequestRedirectFilter.class);
+
+ //登录处理地址
+ super.loginProcessingUrl(this.loginProcessingUrl);
+ super.init(http);
+ }
+
/**
* Create the {@link RequestMatcher} given a loginProcessingUrl
*
@@ -58,7 +86,7 @@ public class AlipayAuthenticationConfigurer extends
*/
@Override
protected RequestMatcher createLoginProcessingUrlMatcher(String loginProcessingUrl) {
- return new AntPathRequestMatcher(loginProcessingUrl);
+ return new AntPathRequestMatcher(loginProcessingUrl, HttpMethod.GET.name());
}
public RequestMatcher getRequestMatcher() {
diff --git a/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/constant/AlipayAuthenticationConstants.java b/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/constant/AlipayAuthenticationConstants.java
index c622632f..4b1a465a 100644
--- a/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/constant/AlipayAuthenticationConstants.java
+++ b/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/constant/AlipayAuthenticationConstants.java
@@ -30,4 +30,9 @@ public class AlipayAuthenticationConstants {
public static final String USER_INFO_SCOPE = "auth_user";
public static final String APP_ID = "app_id";
+
+ public static final String AUTH_CODE = "auth_code";
+
+ public static final String SUCCESS_CODE = "200";
+
}
diff --git a/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/filter/AlipayLoginAuthenticationFilter.java b/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/filter/AlipayLoginAuthenticationFilter.java
index 0bf7f3f1..1210e0e3 100644
--- a/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/filter/AlipayLoginAuthenticationFilter.java
+++ b/eiam-authentication/eiam-authentication-alipay/src/main/java/cn/topiam/employee/authentication/alipay/filter/AlipayLoginAuthenticationFilter.java
@@ -18,25 +18,49 @@
package cn.topiam.employee.authentication.alipay.filter;
import java.io.IOException;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod;
-import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
+import org.springframework.security.oauth2.core.OAuth2Error;
+import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
+import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
+import com.alibaba.fastjson2.JSONObject;
+import com.alipay.easysdk.kernel.Client;
+import com.alipay.easysdk.kernel.Config;
+import com.alipay.easysdk.kernel.Context;
+
+import cn.topiam.employee.authentication.alipay.AlipayIdpOAuth2Config;
+import cn.topiam.employee.authentication.alipay.client.AlipayClient;
+import cn.topiam.employee.authentication.alipay.client.AlipaySystemOauthTokenResponse;
+import cn.topiam.employee.authentication.alipay.client.AlipaySystemUserInfoShareResponse;
+import cn.topiam.employee.authentication.common.authentication.IdpUserDetails;
import cn.topiam.employee.authentication.common.filter.AbstractIdpAuthenticationProcessingFilter;
import cn.topiam.employee.authentication.common.service.UserIdpService;
+import cn.topiam.employee.common.entity.authn.IdentityProviderEntity;
import cn.topiam.employee.common.repository.authentication.IdentityProviderRepository;
import cn.topiam.employee.core.help.ServerHelp;
+import cn.topiam.employee.support.exception.TopIamException;
+import cn.topiam.employee.support.trace.TraceUtils;
import cn.topiam.employee.support.util.HttpUrlUtils;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
+import static com.taobao.api.Constants.SDK_VERSION;
+
+import static cn.topiam.employee.authentication.alipay.constant.AlipayAuthenticationConstants.AUTH_CODE;
import static cn.topiam.employee.authentication.common.IdentityProviderType.ALIPAY_OAUTH;
-import static cn.topiam.employee.authentication.common.constant.AuthenticationConstants.PROVIDER_CODE;
+import static cn.topiam.employee.authentication.common.constant.AuthenticationConstants.*;
+import static cn.topiam.employee.authentication.common.constant.AuthenticationConstants.INVALID_STATE_PARAMETER_ERROR_CODE;
/**
* 支付宝 登录过滤器
@@ -54,14 +78,12 @@ public class AlipayLoginAuthenticationFilter extends AbstractIdpAuthenticationPr
/**
* Creates a new instance
*
- * @param defaultFilterProcessesUrl the {@link String}
* @param userIdpService {@link UserIdpService}
* @param identityProviderRepository {@link IdentityProviderRepository}
*/
- protected AlipayLoginAuthenticationFilter(String defaultFilterProcessesUrl,
- UserIdpService userIdpService,
- IdentityProviderRepository identityProviderRepository) {
- super(defaultFilterProcessesUrl, userIdpService, identityProviderRepository);
+ public AlipayLoginAuthenticationFilter(UserIdpService userIdpService,
+ IdentityProviderRepository identityProviderRepository) {
+ super(REQUEST_MATCHER, userIdpService, identityProviderRepository);
}
@Override
@@ -69,11 +91,76 @@ public class AlipayLoginAuthenticationFilter extends AbstractIdpAuthenticationPr
HttpServletResponse response) throws AuthenticationException,
IOException,
ServletException {
- if (!REQUEST_MATCHER.matches(request)) {
- throw new AuthenticationServiceException(
- "Authentication method not supported: " + request.getMethod());
+ OAuth2AuthorizationRequest authorizationRequest = getOauth2AuthorizationRequest(request,
+ response);
+ TraceUtils.put(UUID.randomUUID().toString());
+ RequestMatcher.MatchResult matcher = REQUEST_MATCHER.matcher(request);
+ Map variables = matcher.getVariables();
+ String providerCode = variables.get(PROVIDER_CODE);
+ String providerId = getIdentityProviderId(providerCode);
+ //code 支付宝为auth_code
+ String code = request.getParameter(AUTH_CODE);
+ if (StringUtils.isEmpty(code)) {
+ logger.error("支付宝登录 auth_code 参数不存在,认证失败");
+ OAuth2Error oauth2Error = new OAuth2Error(INVALID_CODE_PARAMETER_ERROR_CODE);
+ throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
}
- return null;
+ // state
+ String state = request.getParameter(OAuth2ParameterNames.STATE);
+ if (StringUtils.isEmpty(state)) {
+ logger.error("支付宝登录 state 参数不存在,认证失败");
+ OAuth2Error oauth2Error = new OAuth2Error(INVALID_STATE_PARAMETER_ERROR_CODE);
+ throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
+ }
+ //验证state
+ if (!authorizationRequest.getState().equals(state)) {
+ logger.error("支付宝登录 state 匹配不一致,认证失败");
+ OAuth2Error oauth2Error = new OAuth2Error(INVALID_STATE_PARAMETER_ERROR_CODE);
+ throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
+ }
+ //获取身份提供商
+ IdentityProviderEntity provider = getIdentityProviderEntity(providerCode);
+ AlipayIdpOAuth2Config idpOauthConfig = JSONObject.parseObject(provider.getConfig(),
+ AlipayIdpOAuth2Config.class);
+ if (Objects.isNull(idpOauthConfig)) {
+ logger.error("未查询到支付宝登录配置");
+ //无效身份提供商
+ OAuth2Error oauth2Error = new OAuth2Error(INVALID_IDP_CONFIG);
+ throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
+ }
+ try {
+ AlipayClient client = new AlipayClient(
+ new Client(new Context(getConfig(idpOauthConfig), SDK_VERSION)));
+ AlipaySystemOauthTokenResponse token = client.getOauthToken(code);
+ if (!StringUtils.isBlank(token.getCode())) {
+ logger.error("支付宝认证获取 access_token 失败: [" + token.getHttpBody() + "]");
+ throw new TopIamException(token.getSubMsg());
+ }
+ String accessToken = token.getAccessToken();
+ AlipaySystemUserInfoShareResponse userInfo = client.getUserInfo(accessToken);
+ if (!StringUtils.isBlank(userInfo.getCode())) {
+ logger.error("支付宝认证获取用户信息失败: [" + userInfo.getHttpBody() + "]");
+ throw new TopIamException(userInfo.getSubMsg());
+ }
+ //执行逻辑
+ IdpUserDetails idpUserDetails = IdpUserDetails.builder().openId(token.getOpenId())
+ .providerType(ALIPAY_OAUTH).providerCode(providerCode).providerId(providerId)
+ .avatarUrl(userInfo.getAvatar()).nickName(userInfo.getNickName()).build();
+ return attemptAuthentication(request, response, idpUserDetails);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Config getConfig(AlipayIdpOAuth2Config idpOauthConfig) {
+ Config config = new Config();
+ config.protocol = "https";
+ config.gatewayHost = "openapi.alipay.com";
+ config.appId = idpOauthConfig.getAppId();
+ config.signType = "RSA2";
+ config.alipayPublicKey = idpOauthConfig.getAlipayPublicKey();
+ config.merchantPrivateKey = idpOauthConfig.getAppPrivateKey();
+ return config;
}
public static String getLoginUrl(String providerId) {
diff --git a/eiam-console/src/main/console-fe/src/components/IconFont/lib/iconfont.js b/eiam-console/src/main/console-fe/src/components/IconFont/lib/iconfont.js
index e6a97530..47c2c219 100644
--- a/eiam-console/src/main/console-fe/src/components/IconFont/lib/iconfont.js
+++ b/eiam-console/src/main/console-fe/src/components/IconFont/lib/iconfont.js
@@ -15,4 +15,4 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-window._iconfont_svg_string_3203993='',function(c){var l=(l=document.getElementsByTagName("script"))[l.length-1],a=l.getAttribute("data-injectcss"),l=l.getAttribute("data-disable-injectsvg");if(!l){var h,t,i,p,m,d=function(l,a){a.parentNode.insertBefore(l,a)};if(a&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(l){console&&console.log(l)}}h=function(){var l,a=document.createElement("div");a.innerHTML=c._iconfont_svg_string_3203993,(a=a.getElementsByTagName("svg")[0])&&(a.setAttribute("aria-hidden","true"),a.style.position="absolute",a.style.width=0,a.style.height=0,a.style.overflow="hidden",a=a,(l=document.body).firstChild?d(a,l.firstChild):l.appendChild(a))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(h,0):(t=function(){document.removeEventListener("DOMContentLoaded",t,!1),h()},document.addEventListener("DOMContentLoaded",t,!1)):document.attachEvent&&(i=h,p=c.document,m=!1,o(),p.onreadystatechange=function(){"complete"==p.readyState&&(p.onreadystatechange=null,z())})}function z(){m||(m=!0,i())}function o(){try{p.documentElement.doScroll("left")}catch(l){return void setTimeout(o,50)}z()}}(window);
+window._iconfont_svg_string_3203993='',function(c){var l=(l=document.getElementsByTagName("script"))[l.length-1],a=l.getAttribute("data-injectcss"),l=l.getAttribute("data-disable-injectsvg");if(!l){var h,t,i,p,m,d=function(l,a){a.parentNode.insertBefore(l,a)};if(a&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(l){console&&console.log(l)}}h=function(){var l,a=document.createElement("div");a.innerHTML=c._iconfont_svg_string_3203993,(a=a.getElementsByTagName("svg")[0])&&(a.setAttribute("aria-hidden","true"),a.style.position="absolute",a.style.width=0,a.style.height=0,a.style.overflow="hidden",a=a,(l=document.body).firstChild?d(a,l.firstChild):l.appendChild(a))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(h,0):(t=function(){document.removeEventListener("DOMContentLoaded",t,!1),h()},document.addEventListener("DOMContentLoaded",t,!1)):document.attachEvent&&(i=h,p=c.document,m=!1,o(),p.onreadystatechange=function(){"complete"==p.readyState&&(p.onreadystatechange=null,z())})}function z(){m||(m=!0,i())}function o(){try{p.documentElement.doScroll("left")}catch(l){return void setTimeout(o,50)}z()}}(window);
diff --git a/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/components/Config/AliPayOauthConfig.tsx b/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/components/Config/AliPayOauthConfig.tsx
new file mode 100644
index 00000000..bcd9937e
--- /dev/null
+++ b/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/components/Config/AliPayOauthConfig.tsx
@@ -0,0 +1,79 @@
+/*
+ * eiam-console - Employee Identity and Access Management
+ * Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+import { ProFormText } from '@ant-design/pro-components';
+import CallbackUrl from './CallbackUrl';
+import { useIntl } from '@umijs/max';
+
+/**
+ * AliPay Oauth 登录
+ *
+ * @constructor
+ */
+const QqOauthConfig = (props: { isCreate: boolean }) => {
+ const { isCreate } = props;
+ const intl = useIntl();
+
+ return (
+ <>
+
+
+
+ {!isCreate && }
+ >
+ );
+};
+export default QqOauthConfig;
diff --git a/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/components/Config/Config.tsx b/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/components/Config/Config.tsx
index 97b9fbd9..e969a35a 100644
--- a/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/components/Config/Config.tsx
+++ b/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/components/Config/Config.tsx
@@ -26,6 +26,7 @@ import WeWorkScanCode from './WeWorkScanCodeConfig';
import GithubOauthConfig from './GithubOauthConfig';
import GiteeOauthConfig from './GiteeOauthConfig';
import { useIntl } from '@umijs/max';
+import AliPayOauthConfig from '@/pages/authn/IdentityProvider/components/Config/AliPayOauthConfig';
/**
* Config
@@ -43,10 +44,11 @@ const Config = (props: { type: IdentityProviderType | string; isCreate?: boolean
{type === IdentityProviderType.wechatwork_qr && }
{type === IdentityProviderType.dingtalk_qr && }
{type === IdentityProviderType.dingtalk_oauth && }
- {type === IdentityProviderType.qq && }
+ {type === IdentityProviderType.qq_oauth && }
{type === IdentityProviderType.feishu_oauth && }
- {type === IdentityProviderType.gitee && }
- {type === IdentityProviderType.github && }
+ {type === IdentityProviderType.gitee_oauth && }
+ {type === IdentityProviderType.github_oauth && }
+ {type === IdentityProviderType.alipay_oauth && }
{
<>
{!isCreate && }
diff --git a/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/components/Config/GithubOauthConfig.tsx b/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/components/Config/GithubOauthConfig.tsx
index 42dd8f5c..ea74aab4 100644
--- a/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/components/Config/GithubOauthConfig.tsx
+++ b/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/components/Config/GithubOauthConfig.tsx
@@ -32,7 +32,9 @@ const QqOauthConfig = (props: { isCreate: boolean }) => {
<>
{
{
}),
},
{
- value: IdentityProviderType.qq,
+ value: IdentityProviderType.qq_oauth,
label: intl.formatMessage({
id: 'pages.authn.identity_provider.create_modal.form.type.qq',
}),
},
{
- value: IdentityProviderType.github,
+ value: IdentityProviderType.alipay_oauth,
+ label: intl.formatMessage({
+ id: 'pages.authn.identity_provider.create_modal.form.type.alipay_oauth',
+ }),
+ },
+ {
+ value: IdentityProviderType.github_oauth,
label: intl.formatMessage({
id: 'pages.authn.identity_provider.create_modal.form.type.github',
}),
},
{
- value: IdentityProviderType.gitee,
+ value: IdentityProviderType.gitee_oauth,
label: intl.formatMessage({
id: 'pages.authn.identity_provider.create_modal.form.type.gitee',
}),
diff --git a/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/constant.ts b/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/constant.ts
index a774e8d7..451e758e 100644
--- a/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/constant.ts
+++ b/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/constant.ts
@@ -34,10 +34,11 @@ export enum IdentityProviderType {
dingtalk_oauth = 'dingtalk_oauth',
ldap = 'ldap',
//社交
- qq = 'qq_oauth',
- gitee = 'gitee_oauth',
+ qq_oauth = 'qq_oauth',
+ gitee_oauth = 'gitee_oauth',
wechat_qr = 'wechat_qr',
- github = 'github_oauth',
+ github_oauth = 'github_oauth',
+ alipay_oauth = 'alipay_oauth',
}
/**
@@ -48,11 +49,11 @@ export const EXIST_CALLBACK = [
IdentityProviderType.dingtalk_qr,
IdentityProviderType.dingtalk_oauth,
IdentityProviderType.wechat_qr,
- IdentityProviderType.qq,
+ IdentityProviderType.qq_oauth,
IdentityProviderType.feishu_oauth,
IdentityProviderType.feishu_oauth,
- IdentityProviderType.gitee,
- IdentityProviderType.github,
+ IdentityProviderType.gitee_oauth,
+ IdentityProviderType.github_oauth,
];
export const DRAWER_FORM_ITEM_LAYOUT = {
diff --git a/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/locales/zh-CN.ts b/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/locales/zh-CN.ts
index df76c29b..cd109ab9 100644
--- a/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/locales/zh-CN.ts
+++ b/eiam-console/src/main/console-fe/src/pages/authn/IdentityProvider/locales/zh-CN.ts
@@ -36,10 +36,11 @@ export default {
'pages.authn.identity_provider.create_modal.form.type': '创建认证源',
'pages.authn.identity_provider.create_modal.form.type.placeholder': '请选择认证提供商',
'pages.authn.identity_provider.create_modal.form.type.rule.0.message': '请选择认证提供商',
- 'pages.authn.identity_provider.create_modal.form.type.wechat_qr': '微信开放平台扫码认证',
+ 'pages.authn.identity_provider.create_modal.form.type.wechat_qr': '微信扫码认证',
'pages.authn.identity_provider.create_modal.form.type.qq': 'QQ认证',
'pages.authn.identity_provider.create_modal.form.type.gitee': 'Gitee认证',
- 'pages.authn.identity_provider.create_modal.form.type.github': 'Github认证',
+ 'pages.authn.identity_provider.create_modal.form.type.github': 'GitHub认证',
+ 'pages.authn.identity_provider.create_modal.form.type.alipay_oauth': '支付宝认证',
'pages.authn.identity_provider.create_modal.form.type.dingtalk_oauth': '钉钉认证',
'pages.authn.identity_provider.create_modal.form.type.dingtalk_qr': '钉钉扫码认证',
'pages.authn.identity_provider.create_modal.form.type.feishu_oauth': '飞书认证',
@@ -59,8 +60,38 @@ export default {
'在飞书开放平台,开发者后台 -> 企业自建应用,创建企业自建应用',
'pages.authn.identity_provider.config.qq_oauth.app_id.placeholder': '请填写AppId',
'pages.authn.identity_provider.config.qq_oauth.app_secret.placeholder': '请填写AppKey',
+ 'pages.authn.identity_provider.config.gitee_oauth.client_id': '客户端ID',
'pages.authn.identity_provider.config.gitee_oauth.client_id.placeholder': '请填写ClientId',
- 'pages.authn.identity_provider.config.gitee_oauth.client_secret.placeholder': '请填写ClientSecret',
+ 'pages.authn.identity_provider.config.gitee_oauth.client_secret': '客户端秘钥',
+ 'pages.authn.identity_provider.config.gitee_oauth.client_secret.placeholder':
+ '请填写ClientSecret',
+ 'pages.authn.identity_provider.config.gitee_oauth.client_id.extra': 'Gitee应用的Client ID',
+ 'pages.authn.identity_provider.config.gitee_oauth.client_secret.extra':
+ 'Gitee应用生成的Client secret',
+ 'pages.authn.identity_provider.config.github_oauth.client_id':
+ '客户端ID',
+ 'pages.authn.identity_provider.config.github_oauth.client_id.placeholder': '请填写Client ID',
+ 'pages.authn.identity_provider.config.github_oauth.client_secret':
+ '客户端秘钥',
+ 'pages.authn.identity_provider.config.github_oauth.client_secret.placeholder':
+ '请填写Client Secret',
+ 'pages.authn.identity_provider.config.github_oauth.client_id.extra': 'GitHub应用的Client ID',
+ 'pages.authn.identity_provider.config.github_oauth.client_secret.extra':
+ 'GitHub应用生成的Client secret',
+
+ 'pages.authn.identity_provider.config.alipay_oauth.app_id': '应用ID',
+ 'pages.authn.identity_provider.config.alipay_oauth.app_id.placeholder': '请填写应用ID',
+ 'pages.authn.identity_provider.config.alipay_oauth.app_id.extra': 'xxxxxxxxx',
+ 'pages.authn.identity_provider.config.alipay_oauth.app_id.placeholder.extra': 'xxxxxxx',
+ 'pages.authn.identity_provider.config.alipay_oauth.app_private_key': '应用私钥',
+ 'pages.authn.identity_provider.config.alipay_oauth.app_private_key.placeholder':
+ '请填写应用私钥',
+ 'pages.authn.identity_provider.config.alipay_oauth.app_private_key.extra': 'xxxxxxxxxxx',
+ 'pages.authn.identity_provider.config.alipay_oauth.alipay_public_key': '支付宝公钥',
+ 'pages.authn.identity_provider.config.alipay_oauth.alipay_public_key.placeholder':
+ '请填写支付宝公钥',
+ 'pages.authn.identity_provider.config.alipay_oauth.alipay_public_key.extra': 'xxxxxxxxxxxxx',
+
'pages.authn.identity_provider.config.wechat_scan_code.app_id.extra':
'微信扫码登录开发申请获取的AppId',
'pages.authn.identity_provider.config.wechat_scan_code.app_id.placeholder': '请填写获取的AppId',
@@ -80,8 +111,4 @@ export default {
'pages.authn.identity_provider.config.wework_scan_code.app_secret.placeholder':
'请输入获取的Secret',
'pages.authn.identity_provider.add-success-content': '请复制以下链接访问门户端',
- 'pages.authn.identity_provider.config.github_oauth.client_id.placeholder': '请填写Client ID',
- 'pages.authn.identity_provider.config.github_oauth.client_secret.placeholder': '请填写Client Secret',
- 'pages.authn.identity_provider.config.github_oauth.client_id.extra': 'GitHub应用的Client ID',
- 'pages.authn.identity_provider.config.github_oauth.client_secret.extra': 'GitHub应用生成的Client secret',
};
diff --git a/eiam-console/src/main/java/cn/topiam/employee/console/converter/authn/IdentityProviderConverter.java b/eiam-console/src/main/java/cn/topiam/employee/console/converter/authn/IdentityProviderConverter.java
index 945b7fac..7c7ceb35 100644
--- a/eiam-console/src/main/java/cn/topiam/employee/console/converter/authn/IdentityProviderConverter.java
+++ b/eiam-console/src/main/java/cn/topiam/employee/console/converter/authn/IdentityProviderConverter.java
@@ -33,6 +33,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
+import cn.topiam.employee.authentication.alipay.AlipayIdpOAuth2Config;
import cn.topiam.employee.authentication.common.IdentityProviderCategory;
import cn.topiam.employee.authentication.common.IdentityProviderType;
import cn.topiam.employee.authentication.common.config.IdentityProviderConfig;
@@ -249,7 +250,7 @@ public interface IdentityProviderConverter {
//钉钉扫码
} else if (type.equals(DINGTALK_QR.value())) {
identityProviderConfig = config.to(DingTalkIdpScanCodeConfig.class);
- //钉钉Oauth
+ //钉钉OAuth
} else if (type.equals(DINGTALK_OAUTH.value())) {
identityProviderConfig = config.to(DingTalkIdpOauthConfig.class);
//企业微信扫码
@@ -271,7 +272,7 @@ public interface IdentityProviderConverter {
}
//支付宝认证
else if (type.equals(ALIPAY_OAUTH.value())) {
- identityProviderConfig = config.to(GiteeIdpOAuth2Config.class);
+ identityProviderConfig = config.to(AlipayIdpOAuth2Config.class);
} else {
throw new TopIamException("不支持此身份提供商");
}
diff --git a/eiam-portal/src/main/java/cn/topiam/employee/portal/configuration/security/IdpRedirectParameterMatcher.java b/eiam-portal/src/main/java/cn/topiam/employee/portal/configuration/security/IdpRedirectParameterMatcher.java
index df808200..32a4a4ca 100644
--- a/eiam-portal/src/main/java/cn/topiam/employee/portal/configuration/security/IdpRedirectParameterMatcher.java
+++ b/eiam-portal/src/main/java/cn/topiam/employee/portal/configuration/security/IdpRedirectParameterMatcher.java
@@ -17,15 +17,15 @@
*/
package cn.topiam.employee.portal.configuration.security;
-import cn.topiam.employee.authentication.alipay.filter.AlipayAuthorizationRequestRedirectFilter;
-import cn.topiam.employee.authentication.gitee.filter.GiteeAuthorizationRequestRedirectFilter;
-import cn.topiam.employee.authentication.github.filter.GithubOAuth2AuthorizationRequestRedirectFilter;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
+import cn.topiam.employee.authentication.alipay.filter.AlipayAuthorizationRequestRedirectFilter;
import cn.topiam.employee.authentication.dingtalk.filter.DingtalkOAuth2AuthorizationRequestRedirectFilter;
import cn.topiam.employee.authentication.dingtalk.filter.DingtalkScanCodeAuthorizationRequestGetFilter;
import cn.topiam.employee.authentication.feishu.filter.FeiShuAuthorizationRequestRedirectFilter;
+import cn.topiam.employee.authentication.gitee.filter.GiteeAuthorizationRequestRedirectFilter;
+import cn.topiam.employee.authentication.github.filter.GithubOAuth2AuthorizationRequestRedirectFilter;
import cn.topiam.employee.authentication.qq.filter.QqOAuth2AuthorizationRequestRedirectFilter;
import cn.topiam.employee.authentication.wechat.filter.WeChatScanCodeAuthorizationRequestRedirectFilter;
import cn.topiam.employee.authentication.wechatwork.filter.WeChatWorkScanCodeAuthorizationRequestRedirectFilter;
diff --git a/eiam-portal/src/main/java/cn/topiam/employee/portal/configuration/security/PortalSecurityConfiguration.java b/eiam-portal/src/main/java/cn/topiam/employee/portal/configuration/security/PortalSecurityConfiguration.java
index 0e851736..d8f372f9 100644
--- a/eiam-portal/src/main/java/cn/topiam/employee/portal/configuration/security/PortalSecurityConfiguration.java
+++ b/eiam-portal/src/main/java/cn/topiam/employee/portal/configuration/security/PortalSecurityConfiguration.java
@@ -51,6 +51,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import cn.topiam.employee.audit.event.AuditEventPublish;
+import cn.topiam.employee.authentication.alipay.configurer.AlipayAuthenticationConfigurer;
import cn.topiam.employee.authentication.common.configurer.IdpBindAuthenticationConfigurer;
import cn.topiam.employee.authentication.common.jackjson.AuthenticationJacksonModule;
import cn.topiam.employee.authentication.common.service.UserIdpService;
@@ -59,8 +60,8 @@ import cn.topiam.employee.authentication.dingtalk.configurer.DingtalkScanCodeAut
import cn.topiam.employee.authentication.feishu.configurer.FeiShuScanCodeAuthenticationConfigurer;
import cn.topiam.employee.authentication.gitee.configurer.GiteeAuthenticationConfigurer;
import cn.topiam.employee.authentication.github.configurer.GithubOauthAuthenticationConfigurer;
-import cn.topiam.employee.authentication.otp.mail.MailOtpAuthenticationConfigurer;
-import cn.topiam.employee.authentication.otp.sms.SmsOtpAuthenticationConfigurer;
+import cn.topiam.employee.authentication.otp.mail.configurer.MailOtpAuthenticationConfigurer;
+import cn.topiam.employee.authentication.otp.sms.configurer.SmsOtpAuthenticationConfigurer;
import cn.topiam.employee.authentication.qq.configurer.QqOauthAuthenticationConfigurer;
import cn.topiam.employee.authentication.wechat.configurer.WeChatScanCodeAuthenticationConfigurer;
import cn.topiam.employee.authentication.wechatwork.configurer.WeChatWorkScanCodeAuthenticationConfigurer;
@@ -90,14 +91,15 @@ import cn.topiam.employee.support.security.savedredirect.LoginRedirectParameterF
import static org.springframework.http.HttpMethod.*;
import static org.springframework.security.config.Customizer.withDefaults;
+import static cn.topiam.employee.authentication.alipay.configurer.AlipayAuthenticationConfigurer.alipayOauth;
import static cn.topiam.employee.authentication.common.configurer.IdpBindAuthenticationConfigurer.idpBind;
import static cn.topiam.employee.authentication.dingtalk.configurer.DingtalkOAuth2AuthenticationConfigurer.dingtalkOAuth2;
import static cn.topiam.employee.authentication.dingtalk.configurer.DingtalkScanCodeAuthenticationConfigurer.dingtalkScanCode;
import static cn.topiam.employee.authentication.feishu.configurer.FeiShuScanCodeAuthenticationConfigurer.feiShuScanCode;
import static cn.topiam.employee.authentication.gitee.configurer.GiteeAuthenticationConfigurer.giteeOauth;
import static cn.topiam.employee.authentication.github.configurer.GithubOauthAuthenticationConfigurer.github;
-import static cn.topiam.employee.authentication.otp.mail.MailOtpAuthenticationConfigurer.mailOtp;
-import static cn.topiam.employee.authentication.otp.sms.SmsOtpAuthenticationConfigurer.smsOtp;
+import static cn.topiam.employee.authentication.otp.mail.configurer.MailOtpAuthenticationConfigurer.mailOtp;
+import static cn.topiam.employee.authentication.otp.sms.configurer.SmsOtpAuthenticationConfigurer.smsOtp;
import static cn.topiam.employee.authentication.qq.configurer.QqOauthAuthenticationConfigurer.qq;
import static cn.topiam.employee.authentication.wechat.configurer.WeChatScanCodeAuthenticationConfigurer.weChatScanCode;
import static cn.topiam.employee.authentication.wechatwork.configurer.WeChatWorkScanCodeAuthenticationConfigurer.weChatWorkScanCode;
@@ -217,7 +219,13 @@ public class PortalSecurityConfiguration extends AbstractSecurityConfiguration
requestMatchers.add(giteeCode.getRequestMatcher());
httpSecurity.apply(giteeCode);
- //支付宝 todo
+ //支付宝
+ AlipayAuthenticationConfigurer alipayOauth = alipayOauth(identityProviderRepository, userIdpService)
+ .successHandler(successHandler)
+ .failureHandler(failureHandler)
+ .authenticationDetailsSource(authenticationDetailsSource);
+ requestMatchers.add(alipayOauth.getRequestMatcher());
+ httpSecurity.apply(alipayOauth);
//RequestMatcher
OrRequestMatcher requestMatcher = new OrRequestMatcher(requestMatchers);
diff --git a/eiam-portal/src/main/portal-fe/src/components/IconFont/lib/iconfont.js b/eiam-portal/src/main/portal-fe/src/components/IconFont/lib/iconfont.js
index b724cad7..ba64b0ec 100644
--- a/eiam-portal/src/main/portal-fe/src/components/IconFont/lib/iconfont.js
+++ b/eiam-portal/src/main/portal-fe/src/components/IconFont/lib/iconfont.js
@@ -15,4 +15,4 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-window._iconfont_svg_string_3203993='',function(c){var l=(l=document.getElementsByTagName("script"))[l.length-1],a=l.getAttribute("data-injectcss"),l=l.getAttribute("data-disable-injectsvg");if(!l){var h,t,i,p,m,d=function(l,a){a.parentNode.insertBefore(l,a)};if(a&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(l){console&&console.log(l)}}h=function(){var l,a=document.createElement("div");a.innerHTML=c._iconfont_svg_string_3203993,(a=a.getElementsByTagName("svg")[0])&&(a.setAttribute("aria-hidden","true"),a.style.position="absolute",a.style.width=0,a.style.height=0,a.style.overflow="hidden",a=a,(l=document.body).firstChild?d(a,l.firstChild):l.appendChild(a))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(h,0):(t=function(){document.removeEventListener("DOMContentLoaded",t,!1),h()},document.addEventListener("DOMContentLoaded",t,!1)):document.attachEvent&&(i=h,p=c.document,m=!1,o(),p.onreadystatechange=function(){"complete"==p.readyState&&(p.onreadystatechange=null,z())})}function z(){m||(m=!0,i())}function o(){try{p.documentElement.doScroll("left")}catch(l){return void setTimeout(o,50)}z()}}(window);
+window._iconfont_svg_string_3203993='',function(c){var l=(l=document.getElementsByTagName("script"))[l.length-1],a=l.getAttribute("data-injectcss"),l=l.getAttribute("data-disable-injectsvg");if(!l){var h,t,i,p,m,d=function(l,a){a.parentNode.insertBefore(l,a)};if(a&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(l){console&&console.log(l)}}h=function(){var l,a=document.createElement("div");a.innerHTML=c._iconfont_svg_string_3203993,(a=a.getElementsByTagName("svg")[0])&&(a.setAttribute("aria-hidden","true"),a.style.position="absolute",a.style.width=0,a.style.height=0,a.style.overflow="hidden",a=a,(l=document.body).firstChild?d(a,l.firstChild):l.appendChild(a))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(h,0):(t=function(){document.removeEventListener("DOMContentLoaded",t,!1),h()},document.addEventListener("DOMContentLoaded",t,!1)):document.attachEvent&&(i=h,p=c.document,m=!1,o(),p.onreadystatechange=function(){"complete"==p.readyState&&(p.onreadystatechange=null,z())})}function z(){m||(m=!0,i())}function o(){try{p.documentElement.doScroll("left")}catch(l){return void setTimeout(o,50)}z()}}(window);
diff --git a/eiam-portal/src/main/portal-fe/src/constants/index.tsx b/eiam-portal/src/main/portal-fe/src/constants/index.tsx
index add472e4..b0fdaab0 100644
--- a/eiam-portal/src/main/portal-fe/src/constants/index.tsx
+++ b/eiam-portal/src/main/portal-fe/src/constants/index.tsx
@@ -37,6 +37,7 @@ export enum IDP_TYPE {
QQ_OAUTH = 'qq_oauth',
GITEE_OAUTH = 'gitee_oauth',
GITHUB_OAUTH = 'github_oauth',
+ ALIPAY_OAUTH = 'alipay_oauth',
WEIBO_OAUTH = 'weibo_oauth',
WECHATWORK_QR = 'wechatwork_qr',
}
diff --git a/eiam-portal/src/main/portal-fe/src/pages/Login/Login.tsx b/eiam-portal/src/main/portal-fe/src/pages/Login/Login.tsx
index 252c5435..b69eafb2 100644
--- a/eiam-portal/src/main/portal-fe/src/pages/Login/Login.tsx
+++ b/eiam-portal/src/main/portal-fe/src/pages/Login/Login.tsx
@@ -214,6 +214,21 @@ const Login = () => {
window.open(path, '_self');
};
+ /**
+ * alipay
+ *
+ * @param id
+ */
+ const alipayOauthOnClick = (id: string) => {
+ const query = queryString.parse(history.location.search);
+ const { redirect_uri } = query as { redirect_uri: string };
+ let path = `/api/v1/authorization/alipay_oauth/${id}`;
+ if (redirect_uri) {
+ path = `${path}?redirect_uri=${redirect_uri}`;
+ }
+ window.open(path, '_self');
+ };
+
/**
* 提交
*
@@ -518,6 +533,11 @@ const Login = () => {
githubOauthOnClick(value.code);
return;
}
+ //支付宝,跳转页面
+ if (value.type === IDP_TYPE.ALIPAY_OAUTH) {
+ alipayOauthOnClick(value.code);
+ return;
+ }
//其他方式,跳转页面
else {
setCurrentProvider({