完善支付宝认证

pull/37/head
smallbun 2023-08-26 18:11:06 +08:00
parent b24dda711d
commit 2da0ddec6a
21 changed files with 686 additions and 47 deletions

View File

@ -33,10 +33,23 @@ import jakarta.validation.constraints.NotBlank;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class AlipayIdpOAuth2Config extends IdentityProviderConfig { public class AlipayIdpOAuth2Config extends IdentityProviderConfig {
/** /**
* ID * ID
*/ */
@NotBlank(message = "商户ID不能为空") @NotBlank(message = "商户ID不能为空")
private String appId; private String appId;
/**
*
*/
@NotBlank(message = "应用私钥")
private String appPrivateKey;
/**
*
*/
@NotBlank(message = "支付宝公钥")
private String alipayPublicKey;
} }

View File

@ -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))));
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -17,8 +17,11 @@
*/ */
package cn.topiam.employee.authentication.alipay.configurer; 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.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer; 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.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher; import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher; 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.authentication.common.service.UserIdpService;
import cn.topiam.employee.common.repository.authentication.IdentityProviderRepository; 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 public class AlipayAuthenticationConfigurer extends
AbstractAuthenticationFilterConfigurer<HttpSecurity, AlipayAuthenticationConfigurer, AlipayLoginAuthenticationFilter> { AbstractAuthenticationFilterConfigurer<HttpSecurity, AlipayAuthenticationConfigurer, AlipayLoginAuthenticationFilter> {
@Setter
@NonNull
private String loginProcessingUrl = AlipayLoginAuthenticationFilter.DEFAULT_FILTER_PROCESSES_URI;
private final IdentityProviderRepository identityProviderRepository; private final IdentityProviderRepository identityProviderRepository;
private final UserIdpService userIdpService; private final UserIdpService userIdpService;
@ -49,6 +59,24 @@ public class AlipayAuthenticationConfigurer extends
this.userIdpService = userIdpService; 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 * Create the {@link RequestMatcher} given a loginProcessingUrl
* *
@ -58,7 +86,7 @@ public class AlipayAuthenticationConfigurer extends
*/ */
@Override @Override
protected RequestMatcher createLoginProcessingUrlMatcher(String loginProcessingUrl) { protected RequestMatcher createLoginProcessingUrlMatcher(String loginProcessingUrl) {
return new AntPathRequestMatcher(loginProcessingUrl); return new AntPathRequestMatcher(loginProcessingUrl, HttpMethod.GET.name());
} }
public RequestMatcher getRequestMatcher() { public RequestMatcher getRequestMatcher() {

View File

@ -30,4 +30,9 @@ public class AlipayAuthenticationConstants {
public static final String USER_INFO_SCOPE = "auth_user"; public static final String USER_INFO_SCOPE = "auth_user";
public static final String APP_ID = "app_id"; public static final String APP_ID = "app_id";
public static final String AUTH_CODE = "auth_code";
public static final String SUCCESS_CODE = "200";
} }

View File

@ -18,25 +18,49 @@
package cn.topiam.employee.authentication.alipay.filter; package cn.topiam.employee.authentication.alipay.filter;
import java.io.IOException; 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.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException; 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.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher; 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.filter.AbstractIdpAuthenticationProcessingFilter;
import cn.topiam.employee.authentication.common.service.UserIdpService; 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.common.repository.authentication.IdentityProviderRepository;
import cn.topiam.employee.core.help.ServerHelp; 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 cn.topiam.employee.support.util.HttpUrlUtils;
import jakarta.servlet.ServletException; import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; 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.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 * Creates a new instance
* *
* @param defaultFilterProcessesUrl the {@link String}
* @param userIdpService {@link UserIdpService} * @param userIdpService {@link UserIdpService}
* @param identityProviderRepository {@link IdentityProviderRepository} * @param identityProviderRepository {@link IdentityProviderRepository}
*/ */
protected AlipayLoginAuthenticationFilter(String defaultFilterProcessesUrl, public AlipayLoginAuthenticationFilter(UserIdpService userIdpService,
UserIdpService userIdpService, IdentityProviderRepository identityProviderRepository) {
IdentityProviderRepository identityProviderRepository) { super(REQUEST_MATCHER, userIdpService, identityProviderRepository);
super(defaultFilterProcessesUrl, userIdpService, identityProviderRepository);
} }
@Override @Override
@ -69,11 +91,76 @@ public class AlipayLoginAuthenticationFilter extends AbstractIdpAuthenticationPr
HttpServletResponse response) throws AuthenticationException, HttpServletResponse response) throws AuthenticationException,
IOException, IOException,
ServletException { ServletException {
if (!REQUEST_MATCHER.matches(request)) { OAuth2AuthorizationRequest authorizationRequest = getOauth2AuthorizationRequest(request,
throw new AuthenticationServiceException( response);
"Authentication method not supported: " + request.getMethod()); 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) { public static String getLoginUrl(String providerId) {

File diff suppressed because one or more lines are too long

View File

@ -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;

View File

@ -26,6 +26,7 @@ import WeWorkScanCode from './WeWorkScanCodeConfig';
import GithubOauthConfig from './GithubOauthConfig'; import GithubOauthConfig from './GithubOauthConfig';
import GiteeOauthConfig from './GiteeOauthConfig'; import GiteeOauthConfig from './GiteeOauthConfig';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import AliPayOauthConfig from '@/pages/authn/IdentityProvider/components/Config/AliPayOauthConfig';
/** /**
* Config * Config
@ -43,10 +44,11 @@ const Config = (props: { type: IdentityProviderType | string; isCreate?: boolean
{type === IdentityProviderType.wechatwork_qr && <WeWorkScanCode isCreate={isCreate} />} {type === IdentityProviderType.wechatwork_qr && <WeWorkScanCode isCreate={isCreate} />}
{type === IdentityProviderType.dingtalk_qr && <DingTalkScanCode isCreate={isCreate} />} {type === IdentityProviderType.dingtalk_qr && <DingTalkScanCode isCreate={isCreate} />}
{type === IdentityProviderType.dingtalk_oauth && <DingTalkOauthConfig 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.feishu_oauth && <FeiShuScanCodeConfig isCreate={isCreate} />}
{type === IdentityProviderType.gitee && <GiteeOauthConfig isCreate={isCreate} />} {type === IdentityProviderType.gitee_oauth && <GiteeOauthConfig isCreate={isCreate} />}
{type === IdentityProviderType.github && <GithubOauthConfig isCreate={isCreate} />} {type === IdentityProviderType.github_oauth && <GithubOauthConfig isCreate={isCreate} />}
{type === IdentityProviderType.alipay_oauth && <AliPayOauthConfig isCreate={isCreate} />}
<ProFormSwitch <ProFormSwitch
name={['displayed']} name={['displayed']}
extra={intl.formatMessage({ extra={intl.formatMessage({

View File

@ -32,20 +32,30 @@ const GiteeOauthConfig = (props: { isCreate: boolean }) => {
<> <>
<ProFormText <ProFormText
name={['config', 'clientId']} name={['config', 'clientId']}
label="ClientId" label={intl.formatMessage({
id: 'pages.authn.identity_provider.config.gitee_oauth.client_id',
})}
rules={[{ required: true }]} rules={[{ required: true }]}
fieldProps={{ autoComplete: 'off' }} fieldProps={{ autoComplete: 'off' }}
placeholder={intl.formatMessage({ placeholder={intl.formatMessage({
id: 'pages.authn.identity_provider.config.gitee_oauth.client_id.placeholder', 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 <ProFormText.Password
rules={[{ required: true }]} rules={[{ required: true }]}
name={['config', 'clientSecret']} name={['config', 'clientSecret']}
label="ClientSecret" label={intl.formatMessage({
id: 'pages.authn.identity_provider.config.gitee_oauth.client_secret',
})}
placeholder={intl.formatMessage({ placeholder={intl.formatMessage({
id: 'pages.authn.identity_provider.config.gitee_oauth.client_secret.placeholder', 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' }} fieldProps={{ autoComplete: 'off' }}
/> />
{!isCreate && <CallbackUrl />} {!isCreate && <CallbackUrl />}

View File

@ -32,7 +32,9 @@ const QqOauthConfig = (props: { isCreate: boolean }) => {
<> <>
<ProFormText <ProFormText
name={['config', 'clientId']} name={['config', 'clientId']}
label="CilentId" label={intl.formatMessage({
id: 'pages.authn.identity_provider.config.github_oauth.client_id',
})}
rules={[{ required: true }]} rules={[{ required: true }]}
fieldProps={{ autoComplete: 'off' }} fieldProps={{ autoComplete: 'off' }}
placeholder={intl.formatMessage({ placeholder={intl.formatMessage({
@ -45,7 +47,9 @@ const QqOauthConfig = (props: { isCreate: boolean }) => {
<ProFormText.Password <ProFormText.Password
rules={[{ required: true }]} rules={[{ required: true }]}
name={['config', 'clientSecret']} name={['config', 'clientSecret']}
label="ClientSecret" label={intl.formatMessage({
id: 'pages.authn.identity_provider.config.github_oauth.client_secret',
})}
placeholder={intl.formatMessage({ placeholder={intl.formatMessage({
id: 'pages.authn.identity_provider.config.github_oauth.client_secret.placeholder', id: 'pages.authn.identity_provider.config.github_oauth.client_secret.placeholder',
})} })}

View File

@ -116,19 +116,25 @@ export default (props: CreateDrawerProps) => {
}), }),
}, },
{ {
value: IdentityProviderType.qq, value: IdentityProviderType.qq_oauth,
label: intl.formatMessage({ label: intl.formatMessage({
id: 'pages.authn.identity_provider.create_modal.form.type.qq', 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({ label: intl.formatMessage({
id: 'pages.authn.identity_provider.create_modal.form.type.github', id: 'pages.authn.identity_provider.create_modal.form.type.github',
}), }),
}, },
{ {
value: IdentityProviderType.gitee, value: IdentityProviderType.gitee_oauth,
label: intl.formatMessage({ label: intl.formatMessage({
id: 'pages.authn.identity_provider.create_modal.form.type.gitee', id: 'pages.authn.identity_provider.create_modal.form.type.gitee',
}), }),

View File

@ -34,10 +34,11 @@ export enum IdentityProviderType {
dingtalk_oauth = 'dingtalk_oauth', dingtalk_oauth = 'dingtalk_oauth',
ldap = 'ldap', ldap = 'ldap',
//社交 //社交
qq = 'qq_oauth', qq_oauth = 'qq_oauth',
gitee = 'gitee_oauth', gitee_oauth = 'gitee_oauth',
wechat_qr = 'wechat_qr', 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_qr,
IdentityProviderType.dingtalk_oauth, IdentityProviderType.dingtalk_oauth,
IdentityProviderType.wechat_qr, IdentityProviderType.wechat_qr,
IdentityProviderType.qq, IdentityProviderType.qq_oauth,
IdentityProviderType.feishu_oauth, IdentityProviderType.feishu_oauth,
IdentityProviderType.feishu_oauth, IdentityProviderType.feishu_oauth,
IdentityProviderType.gitee, IdentityProviderType.gitee_oauth,
IdentityProviderType.github, IdentityProviderType.github_oauth,
]; ];
export const DRAWER_FORM_ITEM_LAYOUT = { export const DRAWER_FORM_ITEM_LAYOUT = {

View File

@ -36,10 +36,11 @@ export default {
'pages.authn.identity_provider.create_modal.form.type': '创建认证源', '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.placeholder': '请选择认证提供商',
'pages.authn.identity_provider.create_modal.form.type.rule.0.message': '请选择认证提供商', '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.qq': 'QQ认证',
'pages.authn.identity_provider.create_modal.form.type.gitee': 'Gitee认证', '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_oauth': '钉钉认证',
'pages.authn.identity_provider.create_modal.form.type.dingtalk_qr': '钉钉扫码认证', 'pages.authn.identity_provider.create_modal.form.type.dingtalk_qr': '钉钉扫码认证',
'pages.authn.identity_provider.create_modal.form.type.feishu_oauth': '飞书认证', '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_id.placeholder': '请填写AppId',
'pages.authn.identity_provider.config.qq_oauth.app_secret.placeholder': '请填写AppKey', '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_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': 'pages.authn.identity_provider.config.wechat_scan_code.app_id.extra':
'微信扫码登录开发申请获取的AppId', '微信扫码登录开发申请获取的AppId',
'pages.authn.identity_provider.config.wechat_scan_code.app_id.placeholder': '请填写获取的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': 'pages.authn.identity_provider.config.wework_scan_code.app_secret.placeholder':
'请输入获取的Secret', '请输入获取的Secret',
'pages.authn.identity_provider.add-success-content': '请复制以下链接访问门户端', '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',
}; };

View File

@ -33,6 +33,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.querydsl.core.types.ExpressionUtils; import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate; 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.IdentityProviderCategory;
import cn.topiam.employee.authentication.common.IdentityProviderType; import cn.topiam.employee.authentication.common.IdentityProviderType;
import cn.topiam.employee.authentication.common.config.IdentityProviderConfig; import cn.topiam.employee.authentication.common.config.IdentityProviderConfig;
@ -249,7 +250,7 @@ public interface IdentityProviderConverter {
//钉钉扫码 //钉钉扫码
} else if (type.equals(DINGTALK_QR.value())) { } else if (type.equals(DINGTALK_QR.value())) {
identityProviderConfig = config.to(DingTalkIdpScanCodeConfig.class); identityProviderConfig = config.to(DingTalkIdpScanCodeConfig.class);
//钉钉Oauth //钉钉OAuth
} else if (type.equals(DINGTALK_OAUTH.value())) { } else if (type.equals(DINGTALK_OAUTH.value())) {
identityProviderConfig = config.to(DingTalkIdpOauthConfig.class); identityProviderConfig = config.to(DingTalkIdpOauthConfig.class);
//企业微信扫码 //企业微信扫码
@ -271,7 +272,7 @@ public interface IdentityProviderConverter {
} }
//支付宝认证 //支付宝认证
else if (type.equals(ALIPAY_OAUTH.value())) { else if (type.equals(ALIPAY_OAUTH.value())) {
identityProviderConfig = config.to(GiteeIdpOAuth2Config.class); identityProviderConfig = config.to(AlipayIdpOAuth2Config.class);
} else { } else {
throw new TopIamException("不支持此身份提供商"); throw new TopIamException("不支持此身份提供商");
} }

View File

@ -17,15 +17,15 @@
*/ */
package cn.topiam.employee.portal.configuration.security; 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.OrRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher; 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.DingtalkOAuth2AuthorizationRequestRedirectFilter;
import cn.topiam.employee.authentication.dingtalk.filter.DingtalkScanCodeAuthorizationRequestGetFilter; import cn.topiam.employee.authentication.dingtalk.filter.DingtalkScanCodeAuthorizationRequestGetFilter;
import cn.topiam.employee.authentication.feishu.filter.FeiShuAuthorizationRequestRedirectFilter; 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.qq.filter.QqOAuth2AuthorizationRequestRedirectFilter;
import cn.topiam.employee.authentication.wechat.filter.WeChatScanCodeAuthorizationRequestRedirectFilter; import cn.topiam.employee.authentication.wechat.filter.WeChatScanCodeAuthorizationRequestRedirectFilter;
import cn.topiam.employee.authentication.wechatwork.filter.WeChatWorkScanCodeAuthorizationRequestRedirectFilter; import cn.topiam.employee.authentication.wechatwork.filter.WeChatWorkScanCodeAuthorizationRequestRedirectFilter;

View File

@ -51,6 +51,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import cn.topiam.employee.audit.event.AuditEventPublish; 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.configurer.IdpBindAuthenticationConfigurer;
import cn.topiam.employee.authentication.common.jackjson.AuthenticationJacksonModule; import cn.topiam.employee.authentication.common.jackjson.AuthenticationJacksonModule;
import cn.topiam.employee.authentication.common.service.UserIdpService; 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.feishu.configurer.FeiShuScanCodeAuthenticationConfigurer;
import cn.topiam.employee.authentication.gitee.configurer.GiteeAuthenticationConfigurer; import cn.topiam.employee.authentication.gitee.configurer.GiteeAuthenticationConfigurer;
import cn.topiam.employee.authentication.github.configurer.GithubOauthAuthenticationConfigurer; import cn.topiam.employee.authentication.github.configurer.GithubOauthAuthenticationConfigurer;
import cn.topiam.employee.authentication.otp.mail.MailOtpAuthenticationConfigurer; import cn.topiam.employee.authentication.otp.mail.configurer.MailOtpAuthenticationConfigurer;
import cn.topiam.employee.authentication.otp.sms.SmsOtpAuthenticationConfigurer; import cn.topiam.employee.authentication.otp.sms.configurer.SmsOtpAuthenticationConfigurer;
import cn.topiam.employee.authentication.qq.configurer.QqOauthAuthenticationConfigurer; import cn.topiam.employee.authentication.qq.configurer.QqOauthAuthenticationConfigurer;
import cn.topiam.employee.authentication.wechat.configurer.WeChatScanCodeAuthenticationConfigurer; import cn.topiam.employee.authentication.wechat.configurer.WeChatScanCodeAuthenticationConfigurer;
import cn.topiam.employee.authentication.wechatwork.configurer.WeChatWorkScanCodeAuthenticationConfigurer; 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.http.HttpMethod.*;
import static org.springframework.security.config.Customizer.withDefaults; 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.common.configurer.IdpBindAuthenticationConfigurer.idpBind;
import static cn.topiam.employee.authentication.dingtalk.configurer.DingtalkOAuth2AuthenticationConfigurer.dingtalkOAuth2; 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.dingtalk.configurer.DingtalkScanCodeAuthenticationConfigurer.dingtalkScanCode;
import static cn.topiam.employee.authentication.feishu.configurer.FeiShuScanCodeAuthenticationConfigurer.feiShuScanCode; 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.gitee.configurer.GiteeAuthenticationConfigurer.giteeOauth;
import static cn.topiam.employee.authentication.github.configurer.GithubOauthAuthenticationConfigurer.github; 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.mail.configurer.MailOtpAuthenticationConfigurer.mailOtp;
import static cn.topiam.employee.authentication.otp.sms.SmsOtpAuthenticationConfigurer.smsOtp; 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.qq.configurer.QqOauthAuthenticationConfigurer.qq;
import static cn.topiam.employee.authentication.wechat.configurer.WeChatScanCodeAuthenticationConfigurer.weChatScanCode; import static cn.topiam.employee.authentication.wechat.configurer.WeChatScanCodeAuthenticationConfigurer.weChatScanCode;
import static cn.topiam.employee.authentication.wechatwork.configurer.WeChatWorkScanCodeAuthenticationConfigurer.weChatWorkScanCode; import static cn.topiam.employee.authentication.wechatwork.configurer.WeChatWorkScanCodeAuthenticationConfigurer.weChatWorkScanCode;
@ -217,7 +219,13 @@ public class PortalSecurityConfiguration extends AbstractSecurityConfiguration
requestMatchers.add(giteeCode.getRequestMatcher()); requestMatchers.add(giteeCode.getRequestMatcher());
httpSecurity.apply(giteeCode); httpSecurity.apply(giteeCode);
//支付宝 todo //支付宝
AlipayAuthenticationConfigurer alipayOauth = alipayOauth(identityProviderRepository, userIdpService)
.successHandler(successHandler)
.failureHandler(failureHandler)
.authenticationDetailsSource(authenticationDetailsSource);
requestMatchers.add(alipayOauth.getRequestMatcher());
httpSecurity.apply(alipayOauth);
//RequestMatcher //RequestMatcher
OrRequestMatcher requestMatcher = new OrRequestMatcher(requestMatchers); OrRequestMatcher requestMatcher = new OrRequestMatcher(requestMatchers);

File diff suppressed because one or more lines are too long

View File

@ -37,6 +37,7 @@ export enum IDP_TYPE {
QQ_OAUTH = 'qq_oauth', QQ_OAUTH = 'qq_oauth',
GITEE_OAUTH = 'gitee_oauth', GITEE_OAUTH = 'gitee_oauth',
GITHUB_OAUTH = 'github_oauth', GITHUB_OAUTH = 'github_oauth',
ALIPAY_OAUTH = 'alipay_oauth',
WEIBO_OAUTH = 'weibo_oauth', WEIBO_OAUTH = 'weibo_oauth',
WECHATWORK_QR = 'wechatwork_qr', WECHATWORK_QR = 'wechatwork_qr',
} }

View File

@ -214,6 +214,21 @@ const Login = () => {
window.open(path, '_self'); 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); githubOauthOnClick(value.code);
return; return;
} }
//支付宝,跳转页面
if (value.type === IDP_TYPE.ALIPAY_OAUTH) {
alipayOauthOnClick(value.code);
return;
}
//其他方式,跳转页面 //其他方式,跳转页面
else { else {
setCurrentProvider({ setCurrentProvider({