mirror of https://gitee.com/topiam/eiam
✨ 完善支付宝认证
parent
b24dda711d
commit
2da0ddec6a
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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<String, Object> runtime = getRuntime();
|
||||
TeaRequest request = null;
|
||||
long now = System.currentTimeMillis();
|
||||
int retryTimes = 0;
|
||||
while (Tea.allowRetry((java.util.Map<String, Object>) 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<String, String> 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<String, Object> bizParams = new java.util.HashMap<>();
|
||||
java.util.Map<String, String> 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<String, Object> 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<String, Object> runtime = getRuntime();
|
||||
|
||||
TeaRequest request = null;
|
||||
long now = System.currentTimeMillis();
|
||||
int retryTimes = 0;
|
||||
while (Tea.allowRetry((java.util.Map<String, Object>) 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<String, String> 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<String, Object> bizParams = new java.util.HashMap<>();
|
||||
java.util.Map<String, String> textParams = TeaConverter
|
||||
.buildMap(new TeaPair("auth_token", authToken));
|
||||
request = getRequest(systemParams, bizParams, textParams);
|
||||
TeaResponse response = Tea.doAction(request, runtime);
|
||||
|
||||
java.util.Map<String, Object> 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<String, String> systemParams, Map<String, Object> bizParams,
|
||||
Map<String, String> 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<String, Object> 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))));
|
||||
}
|
||||
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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;
|
||||
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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;
|
||||
|
||||
}
|
|
@ -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<HttpSecurity, AlipayAuthenticationConfigurer, AlipayLoginAuthenticationFilter> {
|
||||
@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() {
|
||||
|
|
|
@ -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";
|
||||
|
||||
}
|
||||
|
|
|
@ -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<String, String> 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) {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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 (
|
||||
<>
|
||||
<ProFormText
|
||||
name={['config', 'appId']}
|
||||
label={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.alipay_oauth.app_id',
|
||||
})}
|
||||
rules={[{ required: true }]}
|
||||
fieldProps={{ autoComplete: 'off' }}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.alipay_oauth.app_id.placeholder',
|
||||
})}
|
||||
extra={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.alipay_oauth.app_id.extra',
|
||||
})}
|
||||
/>
|
||||
<ProFormText.Password
|
||||
rules={[{ required: true }]}
|
||||
name={['config', 'appPrivateKey']}
|
||||
label={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.alipay_oauth.app_private_key',
|
||||
})}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.alipay_oauth.app_private_key.placeholder',
|
||||
})}
|
||||
extra={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.alipay_oauth.app_private_key.extra',
|
||||
})}
|
||||
fieldProps={{ autoComplete: 'off' }}
|
||||
/>
|
||||
<ProFormText.Password
|
||||
rules={[{ required: true }]}
|
||||
name={['config', 'alipayPublicKey']}
|
||||
label={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.alipay_oauth.alipay_public_key',
|
||||
})}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.alipay_oauth.alipay_public_key.placeholder',
|
||||
})}
|
||||
extra={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.alipay_oauth.alipay_public_key.extra',
|
||||
})}
|
||||
fieldProps={{ autoComplete: 'off' }}
|
||||
/>
|
||||
{!isCreate && <CallbackUrl />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default QqOauthConfig;
|
|
@ -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 && <WeWorkScanCode isCreate={isCreate} />}
|
||||
{type === IdentityProviderType.dingtalk_qr && <DingTalkScanCode isCreate={isCreate} />}
|
||||
{type === IdentityProviderType.dingtalk_oauth && <DingTalkOauthConfig isCreate={isCreate} />}
|
||||
{type === IdentityProviderType.qq && <QqOauthConfig isCreate={isCreate} />}
|
||||
{type === IdentityProviderType.qq_oauth && <QqOauthConfig isCreate={isCreate} />}
|
||||
{type === IdentityProviderType.feishu_oauth && <FeiShuScanCodeConfig isCreate={isCreate} />}
|
||||
{type === IdentityProviderType.gitee && <GiteeOauthConfig isCreate={isCreate} />}
|
||||
{type === IdentityProviderType.github && <GithubOauthConfig isCreate={isCreate} />}
|
||||
{type === IdentityProviderType.gitee_oauth && <GiteeOauthConfig isCreate={isCreate} />}
|
||||
{type === IdentityProviderType.github_oauth && <GithubOauthConfig isCreate={isCreate} />}
|
||||
{type === IdentityProviderType.alipay_oauth && <AliPayOauthConfig isCreate={isCreate} />}
|
||||
<ProFormSwitch
|
||||
name={['displayed']}
|
||||
extra={intl.formatMessage({
|
||||
|
|
|
@ -32,20 +32,30 @@ const GiteeOauthConfig = (props: { isCreate: boolean }) => {
|
|||
<>
|
||||
<ProFormText
|
||||
name={['config', 'clientId']}
|
||||
label="ClientId"
|
||||
label={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.gitee_oauth.client_id',
|
||||
})}
|
||||
rules={[{ required: true }]}
|
||||
fieldProps={{ autoComplete: 'off' }}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.gitee_oauth.client_id.placeholder',
|
||||
})}
|
||||
extra={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.gitee_oauth.client_id.extra',
|
||||
})}
|
||||
/>
|
||||
<ProFormText.Password
|
||||
rules={[{ required: true }]}
|
||||
name={['config', 'clientSecret']}
|
||||
label="ClientSecret"
|
||||
label={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.gitee_oauth.client_secret',
|
||||
})}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.gitee_oauth.client_secret.placeholder',
|
||||
})}
|
||||
extra={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.gitee_oauth.client_secret.extra',
|
||||
})}
|
||||
fieldProps={{ autoComplete: 'off' }}
|
||||
/>
|
||||
{!isCreate && <CallbackUrl />}
|
||||
|
|
|
@ -32,7 +32,9 @@ const QqOauthConfig = (props: { isCreate: boolean }) => {
|
|||
<>
|
||||
<ProFormText
|
||||
name={['config', 'clientId']}
|
||||
label="CilentId"
|
||||
label={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.github_oauth.client_id',
|
||||
})}
|
||||
rules={[{ required: true }]}
|
||||
fieldProps={{ autoComplete: 'off' }}
|
||||
placeholder={intl.formatMessage({
|
||||
|
@ -45,7 +47,9 @@ const QqOauthConfig = (props: { isCreate: boolean }) => {
|
|||
<ProFormText.Password
|
||||
rules={[{ required: true }]}
|
||||
name={['config', 'clientSecret']}
|
||||
label="ClientSecret"
|
||||
label={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.github_oauth.client_secret',
|
||||
})}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'pages.authn.identity_provider.config.github_oauth.client_secret.placeholder',
|
||||
})}
|
||||
|
|
|
@ -116,19 +116,25 @@ export default (props: CreateDrawerProps) => {
|
|||
}),
|
||||
},
|
||||
{
|
||||
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',
|
||||
}),
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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',
|
||||
};
|
||||
|
|
|
@ -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("不支持此身份提供商");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -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',
|
||||
}
|
||||
|
|
|
@ -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({
|
||||
|
|
Loading…
Reference in New Issue