mirror of https://gitee.com/topiam/eiam
✨ 添加Gitee认证源
parent
2980babe1b
commit
a01e3f924a
|
@ -69,6 +69,12 @@
|
||||||
<artifactId>eiam-authentication-wechatwork</artifactId>
|
<artifactId>eiam-authentication-wechatwork</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- gitee-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.topiam</groupId>
|
||||||
|
<artifactId>eiam-authentication-gitee</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- sms-->
|
<!-- sms-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.topiam</groupId>
|
<groupId>cn.topiam</groupId>
|
||||||
|
|
|
@ -39,6 +39,7 @@ public enum IdentityProviderCategory implements BaseEnum {
|
||||||
Lists.newArrayList(
|
Lists.newArrayList(
|
||||||
IdentityProviderType.QQ,
|
IdentityProviderType.QQ,
|
||||||
IdentityProviderType.WECHAT_QR,
|
IdentityProviderType.WECHAT_QR,
|
||||||
|
IdentityProviderType.GITHUB,
|
||||||
IdentityProviderType.GITHUB)),
|
IdentityProviderType.GITHUB)),
|
||||||
/**
|
/**
|
||||||
* 企业
|
* 企业
|
||||||
|
|
|
@ -64,6 +64,12 @@ public final class IdentityProviderType {
|
||||||
public static final IdentityProviderType WECHAT_WORK_QR = new IdentityProviderType(
|
public static final IdentityProviderType WECHAT_WORK_QR = new IdentityProviderType(
|
||||||
"wechatwork_qr", "企业微信扫码认证", "通过企业微信同步的用户可使用企业微信扫码登录进行身份认证");
|
"wechatwork_qr", "企业微信扫码认证", "通过企业微信同步的用户可使用企业微信扫码登录进行身份认证");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gitee
|
||||||
|
*/
|
||||||
|
public static final IdentityProviderType GITEE_OAUTH = new IdentityProviderType(
|
||||||
|
"gitee_oauth", "Gitee", "通过Gitee进行身份认证");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* QQ认证
|
* QQ认证
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -84,7 +84,7 @@ public class IdpUserDetails {
|
||||||
/**
|
/**
|
||||||
* 额外配置
|
* 额外配置
|
||||||
*/
|
*/
|
||||||
private final Map<String, String> additionalInfo;
|
private final Map<String, Object> additionalInfo;
|
||||||
|
|
||||||
public static IdpUserDetailsBuilder builder() {
|
public static IdpUserDetailsBuilder builder() {
|
||||||
return new IdpUserDetailsBuilder();
|
return new IdpUserDetailsBuilder();
|
||||||
|
@ -130,7 +130,7 @@ public class IdpUserDetails {
|
||||||
return providerType;
|
return providerType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getAdditionalInfo() {
|
public Map<String, Object> getAdditionalInfo() {
|
||||||
return additionalInfo;
|
return additionalInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ public class IdpUserDetails {
|
||||||
final String avatarUrl, final String openId, final String stateCode,
|
final String avatarUrl, final String openId, final String stateCode,
|
||||||
final String unionId, final String providerId, final String providerCode,
|
final String unionId, final String providerId, final String providerCode,
|
||||||
final IdentityProviderType providerType,
|
final IdentityProviderType providerType,
|
||||||
final Map<String, String> additionalInfo) {
|
final Map<String, Object> additionalInfo) {
|
||||||
if (providerId == null) {
|
if (providerId == null) {
|
||||||
throw new NullPointerException("providerId is marked non-null but is null");
|
throw new NullPointerException("providerId is marked non-null but is null");
|
||||||
} else if (providerType == null) {
|
} else if (providerType == null) {
|
||||||
|
@ -181,7 +181,7 @@ public class IdpUserDetails {
|
||||||
|
|
||||||
private IdentityProviderType providerType;
|
private IdentityProviderType providerType;
|
||||||
|
|
||||||
private Map<String, String> additionalInfo;
|
private Map<String, Object> additionalInfo;
|
||||||
|
|
||||||
IdpUserDetailsBuilder() {
|
IdpUserDetailsBuilder() {
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ public class IdpUserDetails {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IdpUserDetailsBuilder additionalInfo(final Map<String, String> additionalInfo) {
|
public IdpUserDetailsBuilder additionalInfo(final Map<String, Object> additionalInfo) {
|
||||||
this.additionalInfo = additionalInfo;
|
this.additionalInfo = additionalInfo;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ 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.util.HttpClientUtils;
|
import cn.topiam.employee.support.util.HttpClientUtils;
|
||||||
|
import cn.topiam.employee.support.util.HttpUrlUtils;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
@ -148,7 +149,7 @@ public class FeiShuLoginAuthenticationFilter extends AbstractIdpAuthenticationPr
|
||||||
public static String getLoginUrl(String providerId) {
|
public static String getLoginUrl(String providerId) {
|
||||||
String url = ServerHelp.getPortalPublicBaseUrl() + FEISHU_OAUTH.getLoginPathPrefix() + "/"
|
String url = ServerHelp.getPortalPublicBaseUrl() + FEISHU_OAUTH.getLoginPathPrefix() + "/"
|
||||||
+ providerId;
|
+ providerId;
|
||||||
return url.replaceAll("(?<!(http:|https:))/+", "/");
|
return HttpUrlUtils.format(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RequestMatcher getRequestMatcher() {
|
public static RequestMatcher getRequestMatcher() {
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
eiam-authentication-gitee - 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/>.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>eiam-authentication</artifactId>
|
||||||
|
<groupId>cn.topiam</groupId>
|
||||||
|
<version>1.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>eiam-authentication-gitee</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<dependencies>
|
||||||
|
<!-- common -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.topiam</groupId>
|
||||||
|
<artifactId>eiam-authentication-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* eiam-authentication-wechat - Employee Identity and Access Management
|
* eiam-authentication-gitee - Employee Identity and Access Management
|
||||||
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
|
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package cn.topiam.employee.authentication.wechat;
|
package cn.topiam.employee.authentication.gitee;
|
||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
|
|
||||||
|
@ -25,61 +25,27 @@ import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信网页登录
|
* Gitee 登录
|
||||||
*
|
*
|
||||||
* @author TopIAM
|
* @author TopIAM
|
||||||
* Created by support@topiam.cn on 2021/12/9 22:07 21:
|
* Created by support@topiam.cn on 2021/12/9 22:07 21:
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class WeChatIdpWebPageConfig extends IdentityProviderConfig {
|
public class GiteeIdpOAuth2Config extends IdentityProviderConfig {
|
||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = -5831048603320371078L;
|
private static final long serialVersionUID = -5831048603320371078L;
|
||||||
/**
|
/**
|
||||||
* 客户端id
|
* 客户端id
|
||||||
*/
|
*/
|
||||||
@NotBlank(message = "应用AppId不能为空")
|
@NotBlank(message = "应用clientId不能为空")
|
||||||
private String appId;
|
private String clientId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 客户端Secret
|
* 客户端Secret
|
||||||
*/
|
*/
|
||||||
@NotBlank(message = "应用AppId不能为空")
|
@NotBlank(message = "应用clientSecret不能为空")
|
||||||
private String appSecret;
|
private String clientSecret;
|
||||||
|
|
||||||
/**
|
|
||||||
* 授权范围
|
|
||||||
*/
|
|
||||||
@NotBlank(message = "授权范围不能为空")
|
|
||||||
private String scope;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 授权URI
|
|
||||||
*/
|
|
||||||
@NotBlank(message = "重定向URI不能为空")
|
|
||||||
private String redirectUri;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 校验文件
|
|
||||||
*/
|
|
||||||
@NotNull(message = "域名校验文件不能为空")
|
|
||||||
private VerifyFile verifyFile;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public static class VerifyFile {
|
|
||||||
/**
|
|
||||||
* 域名校验文件名
|
|
||||||
*/
|
|
||||||
@NotBlank(message = "域名校验文件名不能为空")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 域名校验文件内容
|
|
||||||
*/
|
|
||||||
@NotBlank(message = "域名校验文件内容不能为空")
|
|
||||||
private String content;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* eiam-authentication-gitee - 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.gitee.configurer;
|
||||||
|
|
||||||
|
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;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
import cn.topiam.employee.authentication.common.service.UserIdpService;
|
||||||
|
import cn.topiam.employee.authentication.gitee.filter.GiteeAuthorizationRequestRedirectFilter;
|
||||||
|
import cn.topiam.employee.authentication.gitee.filter.GiteeLoginAuthenticationFilter;
|
||||||
|
import cn.topiam.employee.common.repository.authentication.IdentityProviderRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 认证配置
|
||||||
|
*
|
||||||
|
* @author TopIAM
|
||||||
|
* Created by support@topiam.cn on 2021/9/10 22:58
|
||||||
|
*/
|
||||||
|
public final class GiteeAuthenticationConfigurer extends
|
||||||
|
AbstractAuthenticationFilterConfigurer<HttpSecurity, GiteeAuthenticationConfigurer, GiteeLoginAuthenticationFilter> {
|
||||||
|
|
||||||
|
private final IdentityProviderRepository identityProviderRepository;
|
||||||
|
private final UserIdpService userIdpService;
|
||||||
|
|
||||||
|
GiteeAuthenticationConfigurer(IdentityProviderRepository identityProviderRepository,
|
||||||
|
UserIdpService userIdpService) {
|
||||||
|
Assert.notNull(identityProviderRepository, "identityProviderRepository must not be null");
|
||||||
|
Assert.notNull(userIdpService, "userIdpService must not be null");
|
||||||
|
this.identityProviderRepository = identityProviderRepository;
|
||||||
|
this.userIdpService = userIdpService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the {@link RequestMatcher} given a loginProcessingUrl
|
||||||
|
*
|
||||||
|
* @param loginProcessingUrl creates the {@link RequestMatcher} based upon the
|
||||||
|
* loginProcessingUrl
|
||||||
|
* @return the {@link RequestMatcher} to use based upon the loginProcessingUrl
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected RequestMatcher createLoginProcessingUrlMatcher(String loginProcessingUrl) {
|
||||||
|
return new AntPathRequestMatcher(loginProcessingUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(HttpSecurity http) throws Exception {
|
||||||
|
//Gitee登录认证
|
||||||
|
GiteeLoginAuthenticationFilter loginAuthenticationFilter = new GiteeLoginAuthenticationFilter(
|
||||||
|
identityProviderRepository, userIdpService);
|
||||||
|
this.setAuthenticationFilter(loginAuthenticationFilter);
|
||||||
|
//处理URL
|
||||||
|
super.loginProcessingUrl(GiteeLoginAuthenticationFilter.DEFAULT_FILTER_PROCESSES_URI);
|
||||||
|
super.init(http);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(HttpSecurity http) throws Exception {
|
||||||
|
//Gitee扫码请求重定向
|
||||||
|
GiteeAuthorizationRequestRedirectFilter requestRedirectFilter = new GiteeAuthorizationRequestRedirectFilter(
|
||||||
|
identityProviderRepository);
|
||||||
|
http.addFilterBefore(requestRedirectFilter, OAuth2AuthorizationRequestRedirectFilter.class);
|
||||||
|
http.addFilterBefore(this.getAuthenticationFilter(), OAuth2LoginAuthenticationFilter.class);
|
||||||
|
super.configure(http);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestMatcher getRequestMatcher() {
|
||||||
|
return new OrRequestMatcher(GiteeAuthorizationRequestRedirectFilter.getRequestMatcher(),
|
||||||
|
GiteeLoginAuthenticationFilter.getRequestMatcher());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GiteeAuthenticationConfigurer giteeOauth(IdentityProviderRepository identityProviderRepository,
|
||||||
|
UserIdpService userIdpService) {
|
||||||
|
return new GiteeAuthenticationConfigurer(identityProviderRepository, userIdpService);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* eiam-authentication-gitee - 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.gitee.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gitee 认证常量
|
||||||
|
*
|
||||||
|
* @author TopIAM
|
||||||
|
* Created by support@topiam.cn on 2021/12/9 22:19
|
||||||
|
*/
|
||||||
|
public final class GiteeAuthenticationConstants {
|
||||||
|
|
||||||
|
public static final String AUTHORIZATION_REQUEST = "https://gitee.com/oauth/authorize";
|
||||||
|
public static final String ACCESS_TOKEN = "https://gitee.com/oauth/token";
|
||||||
|
public static final String USER_INFO = "https://gitee.com/api/v5/user";
|
||||||
|
public static final String ERROR_CODE = "error";
|
||||||
|
public static final String USER_INFO_SCOPE = "user_info";
|
||||||
|
public static final String ID = "id";
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* eiam-authentication-gitee - 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.gitee.filter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
|
import org.springframework.security.crypto.keygen.Base64StringKeyGenerator;
|
||||||
|
import org.springframework.security.crypto.keygen.StringKeyGenerator;
|
||||||
|
import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository;
|
||||||
|
import org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizationRequestRepository;
|
||||||
|
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
|
||||||
|
import org.springframework.security.web.DefaultRedirectStrategy;
|
||||||
|
import org.springframework.security.web.RedirectStrategy;
|
||||||
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
|
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
import cn.topiam.employee.authentication.gitee.GiteeIdpOAuth2Config;
|
||||||
|
import cn.topiam.employee.common.entity.authn.IdentityProviderEntity;
|
||||||
|
import cn.topiam.employee.common.repository.authentication.IdentityProviderRepository;
|
||||||
|
import cn.topiam.employee.support.trace.TraceUtils;
|
||||||
|
|
||||||
|
import jakarta.servlet.FilterChain;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import static cn.topiam.employee.authentication.common.IdentityProviderType.GITEE_OAUTH;
|
||||||
|
import static cn.topiam.employee.authentication.common.constant.AuthenticationConstants.PROVIDER_CODE;
|
||||||
|
import static cn.topiam.employee.authentication.gitee.constant.GiteeAuthenticationConstants.AUTHORIZATION_REQUEST;
|
||||||
|
import static cn.topiam.employee.authentication.gitee.constant.GiteeAuthenticationConstants.USER_INFO_SCOPE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gitee 登录请求重定向过滤器
|
||||||
|
*
|
||||||
|
* @author TopIAM
|
||||||
|
* Created by support@topiam.cn on 2022/6/20 21:22
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("DuplicatedCode")
|
||||||
|
public class GiteeAuthorizationRequestRedirectFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory
|
||||||
|
.getLogger(GiteeAuthorizationRequestRedirectFilter.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AntPathRequestMatcher
|
||||||
|
*/
|
||||||
|
public static final AntPathRequestMatcher GITEE_REQUEST_MATCHER = new AntPathRequestMatcher(
|
||||||
|
GITEE_OAUTH.getAuthorizationPathPrefix() + "/" + "{" + PROVIDER_CODE + "}",
|
||||||
|
HttpMethod.GET.name());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重定向策略
|
||||||
|
*/
|
||||||
|
private final RedirectStrategy authorizationRedirectStrategy = new DefaultRedirectStrategy();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 认证请求存储库
|
||||||
|
*/
|
||||||
|
private final AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository = new HttpSessionOAuth2AuthorizationRequestRepository();
|
||||||
|
|
||||||
|
private static final StringKeyGenerator DEFAULT_STATE_GENERATOR = new Base64StringKeyGenerator(
|
||||||
|
Base64.getUrlEncoder());
|
||||||
|
private final IdentityProviderRepository identityProviderRepository;
|
||||||
|
|
||||||
|
public GiteeAuthorizationRequestRedirectFilter(IdentityProviderRepository identityProviderRepository) {
|
||||||
|
this.identityProviderRepository = identityProviderRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(@NonNull HttpServletRequest request,
|
||||||
|
@NonNull HttpServletResponse response,
|
||||||
|
@NonNull FilterChain filterChain) throws IOException,
|
||||||
|
ServletException {
|
||||||
|
RequestMatcher.MatchResult matcher = GITEE_REQUEST_MATCHER.matcher(request);
|
||||||
|
if (!matcher.isMatch()) {
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TraceUtils.put(UUID.randomUUID().toString());
|
||||||
|
Map<String, String> variables = matcher.getVariables();
|
||||||
|
String providerCode = variables.get(PROVIDER_CODE);
|
||||||
|
Optional<IdentityProviderEntity> optional = identityProviderRepository
|
||||||
|
.findByCodeAndEnabledIsTrue(providerCode);
|
||||||
|
if (optional.isEmpty()) {
|
||||||
|
throw new NullPointerException("未查询到身份提供商信息");
|
||||||
|
}
|
||||||
|
IdentityProviderEntity entity = optional.get();
|
||||||
|
GiteeIdpOAuth2Config config = JSONObject.parseObject(entity.getConfig(),
|
||||||
|
GiteeIdpOAuth2Config.class);
|
||||||
|
Assert.notNull(config, "Gitee 登录配置不能为空");
|
||||||
|
//构建授权请求
|
||||||
|
//@formatter:off
|
||||||
|
HashMap<@Nullable String, @Nullable Object> attributes = Maps.newHashMap();
|
||||||
|
OAuth2AuthorizationRequest.Builder builder = OAuth2AuthorizationRequest.authorizationCode()
|
||||||
|
.clientId(config.getClientId())
|
||||||
|
.scopes(Sets.newHashSet(USER_INFO_SCOPE))
|
||||||
|
.authorizationUri(AUTHORIZATION_REQUEST)
|
||||||
|
.redirectUri(GiteeLoginAuthenticationFilter.getLoginUrl(optional.get().getCode()))
|
||||||
|
.state(DEFAULT_STATE_GENERATOR.generateKey())
|
||||||
|
.attributes(attributes);
|
||||||
|
//@formatter:on
|
||||||
|
this.sendRedirectForAuthorization(request, response, builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendRedirectForAuthorization(HttpServletRequest request,
|
||||||
|
HttpServletResponse response,
|
||||||
|
OAuth2AuthorizationRequest authorizationRequest) throws IOException {
|
||||||
|
this.authorizationRequestRepository.saveAuthorizationRequest(authorizationRequest, request,
|
||||||
|
response);
|
||||||
|
this.authorizationRedirectStrategy.sendRedirect(request, response,
|
||||||
|
authorizationRequest.getAuthorizationRequestUri());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RequestMatcher getRequestMatcher() {
|
||||||
|
return GITEE_REQUEST_MATCHER;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,179 @@
|
||||||
|
/*
|
||||||
|
* eiam-authentication-gitee - 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.gitee.filter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
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.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
|
||||||
|
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.authentication.gitee.GiteeIdpOAuth2Config;
|
||||||
|
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.util.HttpClientUtils;
|
||||||
|
import cn.topiam.employee.support.util.HttpUrlUtils;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import static org.springframework.security.oauth2.core.AuthorizationGrantType.AUTHORIZATION_CODE;
|
||||||
|
import static org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames.CLIENT_ID;
|
||||||
|
import static org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames.CLIENT_SECRET;
|
||||||
|
|
||||||
|
import static cn.topiam.employee.authentication.common.IdentityProviderType.*;
|
||||||
|
import static cn.topiam.employee.authentication.common.constant.AuthenticationConstants.*;
|
||||||
|
import static cn.topiam.employee.authentication.gitee.constant.GiteeAuthenticationConstants.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gitee登录过滤器
|
||||||
|
*
|
||||||
|
* @author TopIAM
|
||||||
|
* Created by support@topiam.cn on 2021/12/8 21:11
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("DuplicatedCode")
|
||||||
|
public class GiteeLoginAuthenticationFilter extends AbstractIdpAuthenticationProcessingFilter {
|
||||||
|
|
||||||
|
public final static String DEFAULT_FILTER_PROCESSES_URI = GITEE_OAUTH
|
||||||
|
.getLoginPathPrefix() + "/" + "{" + PROVIDER_CODE + "}";
|
||||||
|
public static final AntPathRequestMatcher REQUEST_MATCHER = new AntPathRequestMatcher(
|
||||||
|
DEFAULT_FILTER_PROCESSES_URI, HttpMethod.GET.name());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance
|
||||||
|
*
|
||||||
|
* @param identityProviderRepository the {@link IdentityProviderRepository}
|
||||||
|
* @param userIdpService {@link UserIdpService}
|
||||||
|
*/
|
||||||
|
public GiteeLoginAuthenticationFilter(IdentityProviderRepository identityProviderRepository,
|
||||||
|
UserIdpService userIdpService) {
|
||||||
|
super(DEFAULT_FILTER_PROCESSES_URI, userIdpService, identityProviderRepository);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gitee认证
|
||||||
|
*
|
||||||
|
* @param request {@link HttpServletRequest}
|
||||||
|
* @param response {@link HttpServletRequest}
|
||||||
|
* @return {@link HttpServletRequest}
|
||||||
|
* @throws AuthenticationException {@link AuthenticationException} AuthenticationException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Authentication attemptAuthentication(HttpServletRequest request,
|
||||||
|
HttpServletResponse response) throws AuthenticationException,
|
||||||
|
IOException {
|
||||||
|
OAuth2AuthorizationRequest authorizationRequest = getOauth2AuthorizationRequest(request,
|
||||||
|
response);
|
||||||
|
RequestMatcher.MatchResult matcher = REQUEST_MATCHER.matcher(request);
|
||||||
|
Map<String, String> variables = matcher.getVariables();
|
||||||
|
String providerCode = variables.get(PROVIDER_CODE);
|
||||||
|
String providerId = getIdentityProviderId(providerCode);
|
||||||
|
//code
|
||||||
|
String code = request.getParameter(OAuth2ParameterNames.CODE);
|
||||||
|
if (StringUtils.isEmpty(code)) {
|
||||||
|
logger.error("Gitee 登录 code 参数不存在,认证失败");
|
||||||
|
OAuth2Error oauth2Error = new OAuth2Error(INVALID_CODE_PARAMETER_ERROR_CODE);
|
||||||
|
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
|
||||||
|
}
|
||||||
|
// state
|
||||||
|
String state = request.getParameter(OAuth2ParameterNames.STATE);
|
||||||
|
if (StringUtils.isEmpty(state)) {
|
||||||
|
logger.error("Gitee 登录 state 参数不存在,认证失败");
|
||||||
|
OAuth2Error oauth2Error = new OAuth2Error(INVALID_STATE_PARAMETER_ERROR_CODE);
|
||||||
|
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
|
||||||
|
}
|
||||||
|
if (!authorizationRequest.getState().equals(state)) {
|
||||||
|
logger.error("Gitee 登录 state 匹配不一致,认证失败");
|
||||||
|
OAuth2Error oauth2Error = new OAuth2Error(INVALID_STATE_PARAMETER_ERROR_CODE);
|
||||||
|
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
|
||||||
|
}
|
||||||
|
//获取身份提供商
|
||||||
|
IdentityProviderEntity provider = getIdentityProviderEntity(providerCode);
|
||||||
|
GiteeIdpOAuth2Config config = JSONObject.parseObject(provider.getConfig(),
|
||||||
|
GiteeIdpOAuth2Config.class);
|
||||||
|
if (Objects.isNull(config)) {
|
||||||
|
logger.error("未查询到 Gitee 登录配置");
|
||||||
|
//无效身份提供商
|
||||||
|
OAuth2Error oauth2Error = new OAuth2Error(
|
||||||
|
AbstractIdpAuthenticationProcessingFilter.INVALID_IDP_CONFIG);
|
||||||
|
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
|
||||||
|
}
|
||||||
|
//获取access token
|
||||||
|
HashMap<String, String> param = new HashMap<>(16);
|
||||||
|
param.put(CLIENT_ID, config.getClientId());
|
||||||
|
param.put(CLIENT_SECRET, config.getClientSecret());
|
||||||
|
param.put(OAuth2ParameterNames.CODE, code);
|
||||||
|
param.put(OAuth2ParameterNames.REDIRECT_URI, getLoginUrl(providerCode));
|
||||||
|
param.put(OAuth2ParameterNames.GRANT_TYPE, AUTHORIZATION_CODE.getValue());
|
||||||
|
JSONObject result = JSON.parseObject(HttpClientUtils.post(ACCESS_TOKEN, param));
|
||||||
|
if (result.containsKey(ERROR_CODE)) {
|
||||||
|
logger.error("获取access_token发生错误: " + result.toJSONString());
|
||||||
|
throw new TopIamException("获取access_token发生错误: " + result.toJSONString());
|
||||||
|
}
|
||||||
|
// 获取user信息
|
||||||
|
param = new HashMap<>(16);
|
||||||
|
param.put(OAuth2ParameterNames.ACCESS_TOKEN,
|
||||||
|
result.getString(OAuth2ParameterNames.ACCESS_TOKEN));
|
||||||
|
result = JSON.parseObject(HttpClientUtils.get(USER_INFO, param));
|
||||||
|
if (result.containsKey(ERROR_CODE)) {
|
||||||
|
logger.error("获取Gitee用户个人信息发生错误: " + result.toJSONString());
|
||||||
|
throw new TopIamException("获取Gitee用户个人信息发生错误: " + result.toJSONString());
|
||||||
|
}
|
||||||
|
// 返回
|
||||||
|
//@formatter:off
|
||||||
|
IdpUserDetails idpUserDetails = IdpUserDetails.builder()
|
||||||
|
.openId(param.get(ID))
|
||||||
|
.nickName((String) result.get("name"))
|
||||||
|
.avatarUrl((String) result.get("avatar_uri"))
|
||||||
|
.email((String) result.get("email"))
|
||||||
|
.providerCode(providerCode)
|
||||||
|
.providerId(providerId)
|
||||||
|
.providerType(GITEE_OAUTH)
|
||||||
|
.additionalInfo(new HashMap<>(result))
|
||||||
|
.build();
|
||||||
|
//@formatter:on
|
||||||
|
return attemptAuthentication(request, response, idpUserDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getLoginUrl(String providerId) {
|
||||||
|
String url = ServerHelp.getPortalPublicBaseUrl() + GITEE_OAUTH.getLoginPathPrefix() + "/"
|
||||||
|
+ providerId;
|
||||||
|
return HttpUrlUtils.format(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RequestMatcher getRequestMatcher() {
|
||||||
|
return REQUEST_MATCHER;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* eiam-authentication-gitee - 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.gitee;
|
|
@ -24,7 +24,6 @@ import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.springframework.http.*;
|
import org.springframework.http.*;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
@ -49,6 +48,7 @@ import cn.topiam.employee.common.repository.authentication.IdentityProviderRepos
|
||||||
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.exception.TopIamException;
|
||||||
import cn.topiam.employee.support.trace.TraceUtils;
|
import cn.topiam.employee.support.trace.TraceUtils;
|
||||||
|
import cn.topiam.employee.support.util.HttpUrlUtils;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
@ -156,7 +156,6 @@ public class GithubOAuth2LoginAuthenticationFilter extends
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static JSONObject request(String url, HttpMethod method, String authorization,
|
private static JSONObject request(String url, HttpMethod method, String authorization,
|
||||||
HashMap<String, String> param) {
|
HashMap<String, String> param) {
|
||||||
RestTemplate client = new RestTemplate();
|
RestTemplate client = new RestTemplate();
|
||||||
|
@ -166,7 +165,7 @@ public class GithubOAuth2LoginAuthenticationFilter extends
|
||||||
if (StringUtils.isNotBlank(authorization)) {
|
if (StringUtils.isNotBlank(authorization)) {
|
||||||
headers.set("Authorization", authorization);
|
headers.set("Authorization", authorization);
|
||||||
}
|
}
|
||||||
HttpEntity requestEntity = new HttpEntity(param, headers);
|
HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(param, headers);
|
||||||
ResponseEntity<String> responseEntity = client.exchange(url, method, requestEntity,
|
ResponseEntity<String> responseEntity = client.exchange(url, method, requestEntity,
|
||||||
String.class);
|
String.class);
|
||||||
return JSON.parseObject(responseEntity.getBody());
|
return JSON.parseObject(responseEntity.getBody());
|
||||||
|
@ -175,7 +174,7 @@ public class GithubOAuth2LoginAuthenticationFilter extends
|
||||||
public static String getLoginUrl(String providerId) {
|
public static String getLoginUrl(String providerId) {
|
||||||
String url = ServerHelp.getPortalPublicBaseUrl() + "/" + GITHUB.getLoginPathPrefix() + "/"
|
String url = ServerHelp.getPortalPublicBaseUrl() + "/" + GITHUB.getLoginPathPrefix() + "/"
|
||||||
+ providerId;
|
+ providerId;
|
||||||
return url.replaceAll("(?<!(http:|https:))/+", "/");
|
return HttpUrlUtils.format(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RequestMatcher getRequestMatcher() {
|
public static RequestMatcher getRequestMatcher() {
|
||||||
|
|
|
@ -48,6 +48,7 @@ import cn.topiam.employee.core.help.ServerHelp;
|
||||||
import cn.topiam.employee.support.exception.TopIamException;
|
import cn.topiam.employee.support.exception.TopIamException;
|
||||||
import cn.topiam.employee.support.trace.TraceUtils;
|
import cn.topiam.employee.support.trace.TraceUtils;
|
||||||
import cn.topiam.employee.support.util.HttpClientUtils;
|
import cn.topiam.employee.support.util.HttpClientUtils;
|
||||||
|
import cn.topiam.employee.support.util.HttpUrlUtils;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
@ -164,7 +165,7 @@ public class QqOAuth2LoginAuthenticationFilter extends AbstractIdpAuthentication
|
||||||
public static String getLoginUrl(String providerId) {
|
public static String getLoginUrl(String providerId) {
|
||||||
String url = ServerHelp.getPortalPublicBaseUrl() + "/" + QQ.getLoginPathPrefix() + "/"
|
String url = ServerHelp.getPortalPublicBaseUrl() + "/" + QQ.getLoginPathPrefix() + "/"
|
||||||
+ providerId;
|
+ providerId;
|
||||||
return url.replaceAll("(?<!(http:|https:))/+", "/");
|
return HttpUrlUtils.format(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RequestMatcher getRequestMatcher() {
|
public static RequestMatcher getRequestMatcher() {
|
||||||
|
|
|
@ -46,6 +46,7 @@ import cn.topiam.employee.common.repository.authentication.IdentityProviderRepos
|
||||||
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.exception.TopIamException;
|
||||||
import cn.topiam.employee.support.util.HttpClientUtils;
|
import cn.topiam.employee.support.util.HttpClientUtils;
|
||||||
|
import cn.topiam.employee.support.util.HttpUrlUtils;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
@ -159,7 +160,7 @@ public class WeChatScanCodeLoginAuthenticationFilter extends
|
||||||
public static String getLoginUrl(String providerId) {
|
public static String getLoginUrl(String providerId) {
|
||||||
String url = ServerHelp.getPortalPublicBaseUrl() + WECHAT_QR.getLoginPathPrefix() + "/"
|
String url = ServerHelp.getPortalPublicBaseUrl() + WECHAT_QR.getLoginPathPrefix() + "/"
|
||||||
+ providerId;
|
+ providerId;
|
||||||
return url.replaceAll("(?<!(http:|https:))/+", "/");
|
return HttpUrlUtils.format(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RequestMatcher getRequestMatcher() {
|
public static RequestMatcher getRequestMatcher() {
|
||||||
|
|
|
@ -50,6 +50,7 @@ import cn.topiam.employee.common.repository.authentication.IdentityProviderRepos
|
||||||
import cn.topiam.employee.core.help.ServerHelp;
|
import cn.topiam.employee.core.help.ServerHelp;
|
||||||
import cn.topiam.employee.support.trace.TraceUtils;
|
import cn.topiam.employee.support.trace.TraceUtils;
|
||||||
import cn.topiam.employee.support.util.HttpClientUtils;
|
import cn.topiam.employee.support.util.HttpClientUtils;
|
||||||
|
import cn.topiam.employee.support.util.HttpUrlUtils;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
@ -191,7 +192,7 @@ public class WeChatWorkScanCodeLoginAuthenticationFilter extends
|
||||||
public static String getLoginUrl(String providerId) {
|
public static String getLoginUrl(String providerId) {
|
||||||
String url = ServerHelp.getPortalPublicBaseUrl() + WECHAT_WORK_QR.getLoginPathPrefix() + "/"
|
String url = ServerHelp.getPortalPublicBaseUrl() + WECHAT_WORK_QR.getLoginPathPrefix() + "/"
|
||||||
+ providerId;
|
+ providerId;
|
||||||
return url.replaceAll("(?<!(http:|https:))/+", "/");
|
return HttpUrlUtils.format(url);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
<module>eiam-authentication-mail</module>
|
<module>eiam-authentication-mail</module>
|
||||||
<module>eiam-authentication-sms</module>
|
<module>eiam-authentication-sms</module>
|
||||||
<module>eiam-authentication-github</module>
|
<module>eiam-authentication-github</module>
|
||||||
|
<module>eiam-authentication-gitee</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -102,7 +102,7 @@
|
||||||
"eslint": "^8.47.0",
|
"eslint": "^8.47.0",
|
||||||
"husky": "^8.0.3",
|
"husky": "^8.0.3",
|
||||||
"lint-staged": "^14.0.0",
|
"lint-staged": "^14.0.0",
|
||||||
"prettier": "^3.0.1",
|
"prettier": "^3.0.2",
|
||||||
"typescript": "^5.1.6",
|
"typescript": "^5.1.6",
|
||||||
"umi-presets-pro": "^2.0.3"
|
"umi-presets-pro": "^2.0.3"
|
||||||
},
|
},
|
||||||
|
|
|
@ -34,6 +34,7 @@ export const ICON_LIST = {
|
||||||
wechatwork_qr: <IconFont name="icon-qiyeweixin" />,
|
wechatwork_qr: <IconFont name="icon-qiyeweixin" />,
|
||||||
feishu_oauth: <IconFont name="icon-feishu" />,
|
feishu_oauth: <IconFont name="icon-feishu" />,
|
||||||
qq_oauth: <IconFont name="icon-qq" />,
|
qq_oauth: <IconFont name="icon-qq" />,
|
||||||
|
gitee_oauth: <IconFont name="icon-gitee" />,
|
||||||
weibo_oauth: <IconFont name="icon-weibo" />,
|
weibo_oauth: <IconFont name="icon-weibo" />,
|
||||||
github_oauth: <IconFont name="icon-github" />,
|
github_oauth: <IconFont name="icon-github" />,
|
||||||
google_oauth: <IconFont name="icon-google" />,
|
google_oauth: <IconFont name="icon-google" />,
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -24,6 +24,7 @@ import QqOauthConfig from './QqOauthConfig';
|
||||||
import WeChatScanCode from './WeChatScanCodeConfig';
|
import WeChatScanCode from './WeChatScanCodeConfig';
|
||||||
import WeWorkScanCode from './WeWorkScanCodeConfig';
|
import WeWorkScanCode from './WeWorkScanCodeConfig';
|
||||||
import GithubOauthConfig from './GithubOauthConfig';
|
import GithubOauthConfig from './GithubOauthConfig';
|
||||||
|
import GiteeOauthConfig from './GiteeOauthConfig';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,6 +45,7 @@ const Config = (props: { type: IdentityProviderType | string; isCreate?: boolean
|
||||||
{type === IdentityProviderType.dingtalk_oauth && <DingTalkOauthConfig isCreate={isCreate} />}
|
{type === IdentityProviderType.dingtalk_oauth && <DingTalkOauthConfig isCreate={isCreate} />}
|
||||||
{type === IdentityProviderType.qq && <QqOauthConfig isCreate={isCreate} />}
|
{type === IdentityProviderType.qq && <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.github && <GithubOauthConfig isCreate={isCreate} />}
|
{type === IdentityProviderType.github && <GithubOauthConfig isCreate={isCreate} />}
|
||||||
<ProFormSwitch
|
<ProFormSwitch
|
||||||
name={['displayed']}
|
name={['displayed']}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* 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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gitee Oauth 登录
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
const GiteeOauthConfig = (props: { isCreate: boolean }) => {
|
||||||
|
const { isCreate } = props;
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ProFormText
|
||||||
|
name={['config', 'clientId']}
|
||||||
|
label="ClientId"
|
||||||
|
rules={[{ required: true }]}
|
||||||
|
fieldProps={{ autoComplete: 'off' }}
|
||||||
|
placeholder={intl.formatMessage({
|
||||||
|
id: 'pages.authn.identity_provider.config.gitee_oauth.client_id.placeholder',
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
<ProFormText.Password
|
||||||
|
rules={[{ required: true }]}
|
||||||
|
name={['config', 'clientSecret']}
|
||||||
|
label="ClientSecret"
|
||||||
|
placeholder={intl.formatMessage({
|
||||||
|
id: 'pages.authn.identity_provider.config.gitee_oauth.client_secret.placeholder',
|
||||||
|
})}
|
||||||
|
fieldProps={{ autoComplete: 'off' }}
|
||||||
|
/>
|
||||||
|
{!isCreate && <CallbackUrl />}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default GiteeOauthConfig;
|
|
@ -127,6 +127,12 @@ export default (props: CreateDrawerProps) => {
|
||||||
id: 'pages.authn.identity_provider.create_modal.form.type.github',
|
id: 'pages.authn.identity_provider.create_modal.form.type.github',
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
value: IdentityProviderType.gitee,
|
||||||
|
label: intl.formatMessage({
|
||||||
|
id: 'pages.authn.identity_provider.create_modal.form.type.gitee',
|
||||||
|
}),
|
||||||
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -35,6 +35,7 @@ export enum IdentityProviderType {
|
||||||
ldap = 'ldap',
|
ldap = 'ldap',
|
||||||
//社交
|
//社交
|
||||||
qq = 'qq_oauth',
|
qq = 'qq_oauth',
|
||||||
|
gitee = 'gitee_oauth',
|
||||||
wechat_qr = 'wechat_qr',
|
wechat_qr = 'wechat_qr',
|
||||||
github = 'github_oauth',
|
github = 'github_oauth',
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ export default {
|
||||||
'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.github': 'Github认证',
|
'pages.authn.identity_provider.create_modal.form.type.github': 'Github认证',
|
||||||
'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': '钉钉扫码认证',
|
||||||
|
@ -56,7 +57,10 @@ export default {
|
||||||
'pages.authn.identity_provider.config.ding_talk_oauth.app_secret.placeholder': '请填写AppSecret',
|
'pages.authn.identity_provider.config.ding_talk_oauth.app_secret.placeholder': '请填写AppSecret',
|
||||||
'pages.authn.identity_provider.config.feishu_scan_code.app_id.extra':
|
'pages.authn.identity_provider.config.feishu_scan_code.app_id.extra':
|
||||||
'在飞书开放平台,开发者后台 -> 企业自建应用,创建企业自建应用',
|
'在飞书开放平台,开发者后台 -> 企业自建应用,创建企业自建应用',
|
||||||
'pages.authn.identity_provider.config.qq_oauth.app_secret.placeholder': '请填写appKey',
|
'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.placeholder': '请填写ClientId',
|
||||||
|
'pages.authn.identity_provider.config.gitee_oauth.client_secret.placeholder': '请填写ClientSecret',
|
||||||
'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',
|
||||||
|
|
|
@ -39,9 +39,9 @@ import cn.topiam.employee.authentication.common.config.IdentityProviderConfig;
|
||||||
import cn.topiam.employee.authentication.dingtalk.DingTalkIdpOauthConfig;
|
import cn.topiam.employee.authentication.dingtalk.DingTalkIdpOauthConfig;
|
||||||
import cn.topiam.employee.authentication.dingtalk.DingTalkIdpScanCodeConfig;
|
import cn.topiam.employee.authentication.dingtalk.DingTalkIdpScanCodeConfig;
|
||||||
import cn.topiam.employee.authentication.feishu.FeiShuIdpScanCodeConfig;
|
import cn.topiam.employee.authentication.feishu.FeiShuIdpScanCodeConfig;
|
||||||
|
import cn.topiam.employee.authentication.gitee.GiteeIdpOAuth2Config;
|
||||||
import cn.topiam.employee.authentication.github.GithubIdpOauthConfig;
|
import cn.topiam.employee.authentication.github.GithubIdpOauthConfig;
|
||||||
import cn.topiam.employee.authentication.qq.QqIdpOauthConfig;
|
import cn.topiam.employee.authentication.qq.QqIdpOauthConfig;
|
||||||
import cn.topiam.employee.authentication.wechat.WeChatIdpScanCodeConfig;
|
|
||||||
import cn.topiam.employee.authentication.wechatwork.WeChatWorkIdpScanCodeConfig;
|
import cn.topiam.employee.authentication.wechatwork.WeChatWorkIdpScanCodeConfig;
|
||||||
import cn.topiam.employee.common.entity.authn.IdentityProviderEntity;
|
import cn.topiam.employee.common.entity.authn.IdentityProviderEntity;
|
||||||
import cn.topiam.employee.common.entity.authn.QIdentityProviderEntity;
|
import cn.topiam.employee.common.entity.authn.QIdentityProviderEntity;
|
||||||
|
@ -245,7 +245,7 @@ public interface IdentityProviderConverter {
|
||||||
IdentityProviderConfig identityProviderConfig;
|
IdentityProviderConfig identityProviderConfig;
|
||||||
//微信扫码
|
//微信扫码
|
||||||
if (type.equals(WECHAT_QR.value())) {
|
if (type.equals(WECHAT_QR.value())) {
|
||||||
identityProviderConfig = config.to(WeChatIdpScanCodeConfig.class);
|
identityProviderConfig = config.to(GiteeIdpOAuth2Config.class);
|
||||||
//钉钉扫码
|
//钉钉扫码
|
||||||
} else if (type.equals(DINGTALK_QR.value())) {
|
} else if (type.equals(DINGTALK_QR.value())) {
|
||||||
identityProviderConfig = config.to(DingTalkIdpScanCodeConfig.class);
|
identityProviderConfig = config.to(DingTalkIdpScanCodeConfig.class);
|
||||||
|
@ -264,6 +264,10 @@ public interface IdentityProviderConverter {
|
||||||
//GITHUB认证
|
//GITHUB认证
|
||||||
} else if (type.equals(GITHUB.value())) {
|
} else if (type.equals(GITHUB.value())) {
|
||||||
identityProviderConfig = config.to(GithubIdpOauthConfig.class);
|
identityProviderConfig = config.to(GithubIdpOauthConfig.class);
|
||||||
|
}
|
||||||
|
//Gitee
|
||||||
|
else if (type.equals(GITEE_OAUTH.value())) {
|
||||||
|
identityProviderConfig = config.to(GiteeIdpOAuth2Config.class);
|
||||||
} else {
|
} else {
|
||||||
throw new TopIamException("不支持此身份提供商");
|
throw new TopIamException("不支持此身份提供商");
|
||||||
}
|
}
|
||||||
|
@ -318,6 +322,9 @@ public interface IdentityProviderConverter {
|
||||||
if (GITHUB.value().equals(type)) {
|
if (GITHUB.value().equals(type)) {
|
||||||
return GITHUB;
|
return GITHUB;
|
||||||
}
|
}
|
||||||
|
if (GITEE_OAUTH.value().equals(type)) {
|
||||||
|
return GITEE_OAUTH;
|
||||||
|
}
|
||||||
throw new IllegalArgumentException("未知身份提供商类型");
|
throw new IllegalArgumentException("未知身份提供商类型");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@ import cn.topiam.employee.authentication.common.service.UserIdpService;
|
||||||
import cn.topiam.employee.authentication.dingtalk.configurer.DingtalkOAuth2AuthenticationConfigurer;
|
import cn.topiam.employee.authentication.dingtalk.configurer.DingtalkOAuth2AuthenticationConfigurer;
|
||||||
import cn.topiam.employee.authentication.dingtalk.configurer.DingtalkScanCodeAuthenticationConfigurer;
|
import cn.topiam.employee.authentication.dingtalk.configurer.DingtalkScanCodeAuthenticationConfigurer;
|
||||||
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.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.MailOtpAuthenticationConfigurer;
|
||||||
import cn.topiam.employee.authentication.otp.sms.SmsOtpAuthenticationConfigurer;
|
import cn.topiam.employee.authentication.otp.sms.SmsOtpAuthenticationConfigurer;
|
||||||
|
@ -93,6 +94,7 @@ import static cn.topiam.employee.authentication.common.configurer.IdpBindAuthent
|
||||||
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.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.MailOtpAuthenticationConfigurer.mailOtp;
|
||||||
import static cn.topiam.employee.authentication.otp.sms.SmsOtpAuthenticationConfigurer.smsOtp;
|
import static cn.topiam.employee.authentication.otp.sms.SmsOtpAuthenticationConfigurer.smsOtp;
|
||||||
|
@ -206,6 +208,15 @@ public class PortalSecurityConfiguration extends AbstractSecurityConfiguration
|
||||||
requestMatchers.add(feiShuScanCode.getRequestMatcher());
|
requestMatchers.add(feiShuScanCode.getRequestMatcher());
|
||||||
httpSecurity.apply(feiShuScanCode);
|
httpSecurity.apply(feiShuScanCode);
|
||||||
|
|
||||||
|
|
||||||
|
//Gitee
|
||||||
|
GiteeAuthenticationConfigurer giteeCode = giteeOauth(identityProviderRepository, userIdpService)
|
||||||
|
.successHandler(successHandler)
|
||||||
|
.failureHandler(failureHandler)
|
||||||
|
.authenticationDetailsSource(authenticationDetailsSource);
|
||||||
|
requestMatchers.add(giteeCode.getRequestMatcher());
|
||||||
|
httpSecurity.apply(giteeCode);
|
||||||
|
|
||||||
//RequestMatcher
|
//RequestMatcher
|
||||||
OrRequestMatcher requestMatcher = new OrRequestMatcher(requestMatchers);
|
OrRequestMatcher requestMatcher = new OrRequestMatcher(requestMatchers);
|
||||||
//社交授权请求重定向匹配器
|
//社交授权请求重定向匹配器
|
||||||
|
|
|
@ -97,7 +97,7 @@
|
||||||
"eslint": "^8.47.0",
|
"eslint": "^8.47.0",
|
||||||
"husky": "^8.0.3",
|
"husky": "^8.0.3",
|
||||||
"lint-staged": "^14.0.0",
|
"lint-staged": "^14.0.0",
|
||||||
"prettier": "^3.0.1",
|
"prettier": "^3.0.2",
|
||||||
"typescript": "^5.1.6",
|
"typescript": "^5.1.6",
|
||||||
"umi-presets-pro": "^2.0.3"
|
"umi-presets-pro": "^2.0.3"
|
||||||
},
|
},
|
||||||
|
|
|
@ -34,6 +34,7 @@ export const ICON_LIST = {
|
||||||
wechatwork_qr: <IconFont name="icon-qiyeweixin" />,
|
wechatwork_qr: <IconFont name="icon-qiyeweixin" />,
|
||||||
feishu_oauth: <IconFont name="icon-feishu" />,
|
feishu_oauth: <IconFont name="icon-feishu" />,
|
||||||
qq_oauth: <IconFont name="icon-qq" />,
|
qq_oauth: <IconFont name="icon-qq" />,
|
||||||
|
gitee_oauth: <IconFont name="icon-gitee" />,
|
||||||
weibo_oauth: <IconFont name="icon-weibo" />,
|
weibo_oauth: <IconFont name="icon-weibo" />,
|
||||||
github_oauth: <IconFont name="icon-github" />,
|
github_oauth: <IconFont name="icon-github" />,
|
||||||
google_oauth: <IconFont name="icon-google" />,
|
google_oauth: <IconFont name="icon-google" />,
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -35,6 +35,7 @@ export enum IDP_TYPE {
|
||||||
FEISHU_OAUTH = 'feishu_oauth',
|
FEISHU_OAUTH = 'feishu_oauth',
|
||||||
DINGTALK_OAUTH = 'dingtalk_oauth',
|
DINGTALK_OAUTH = 'dingtalk_oauth',
|
||||||
QQ_OAUTH = 'qq_oauth',
|
QQ_OAUTH = 'qq_oauth',
|
||||||
|
GITEE_OAUTH = 'gitee_oauth',
|
||||||
GITHUB_OAUTH = 'github_oauth',
|
GITHUB_OAUTH = 'github_oauth',
|
||||||
WEIBO_OAUTH = 'weibo_oauth',
|
WEIBO_OAUTH = 'weibo_oauth',
|
||||||
WECHATWORK_QR = 'wechatwork_qr',
|
WECHATWORK_QR = 'wechatwork_qr',
|
||||||
|
|
|
@ -199,6 +199,21 @@ const Login = () => {
|
||||||
window.open(path, '_self');
|
window.open(path, '_self');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gitee
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
const giteeOauthOnClick = (id: string) => {
|
||||||
|
const query = queryString.parse(history.location.search);
|
||||||
|
const { redirect_uri } = query as { redirect_uri: string };
|
||||||
|
let path = `/api/v1/authorization/gitee_oauth/${id}`;
|
||||||
|
if (redirect_uri) {
|
||||||
|
path = `${path}?redirect_uri=${redirect_uri}`;
|
||||||
|
}
|
||||||
|
window.open(path, '_self');
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提交
|
* 提交
|
||||||
*
|
*
|
||||||
|
@ -493,6 +508,11 @@ const Login = () => {
|
||||||
weiBoOauthOnClick(value.code);
|
weiBoOauthOnClick(value.code);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//gitee
|
||||||
|
if (value.type === IDP_TYPE.GITEE_OAUTH) {
|
||||||
|
giteeOauthOnClick(value.code);
|
||||||
|
return;
|
||||||
|
}
|
||||||
//GITHUB,跳转页面
|
//GITHUB,跳转页面
|
||||||
if (value.type === IDP_TYPE.GITHUB_OAUTH) {
|
if (value.type === IDP_TYPE.GITHUB_OAUTH) {
|
||||||
githubOauthOnClick(value.code);
|
githubOauthOnClick(value.code);
|
||||||
|
|
Loading…
Reference in New Issue