移除第三方登录模块

This commit is contained in:
jiangdingxuan 2024-01-09 16:03:43 +08:00
parent 13c9b8af85
commit 8a00d31fe9
20 changed files with 4 additions and 1300 deletions

13
pom.xml
View File

@ -38,7 +38,6 @@
<mapstruct-plus.lombok.version>0.2.0</mapstruct-plus.lombok.version>
<lombok.version>1.18.30</lombok.version>
<bouncycastle.version>1.76</bouncycastle.version>
<justauth.version>1.16.6</justauth.version>
<!-- 离线IP地址定位库 -->
<ip2region.version>2.7.0</ip2region.version>
@ -107,13 +106,6 @@
<scope>import</scope>
</dependency>
<!-- JustAuth 的依赖配置-->
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>${justauth.version}</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
@ -426,11 +418,6 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>

View File

@ -1,35 +0,0 @@
package org.dromara.common.core.domain.model;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 三方登录对象
*
* @author Lion Li
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class SocialLoginBody extends LoginBody {
/**
* 第三方登录平台
*/
@NotBlank(message = "{social.source.not.blank}")
private String source;
/**
* 第三方登录code
*/
@NotBlank(message = "{social.code.not.blank}")
private String socialCode;
/**
* 第三方登录socialState
*/
@NotBlank(message = "{social.state.not.blank}")
private String socialState;
}

View File

@ -1,24 +0,0 @@
package org.dromara.common.social.config;
import me.zhyd.oauth.cache.AuthStateCache;
import org.dromara.common.social.config.properties.SocialProperties;
import org.dromara.common.social.utils.AuthRedisStateCache;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Social 配置属性
* @author thiszhc
*/
@Configuration
@EnableConfigurationProperties(SocialProperties.class)
public class SocialAutoConfiguration {
@Bean
public AuthStateCache authStateCache() {
return new AuthRedisStateCache();
}
}

View File

@ -1,68 +0,0 @@
package org.dromara.common.social.config.properties;
import lombok.Data;
/**
* 社交登录配置
*
* @author thiszhc
*/
@Data
public class SocialLoginConfigProperties {
/**
* 应用 ID
*/
private String clientId;
/**
* 应用密钥
*/
private String clientSecret;
/**
* 回调地址
*/
private String redirectUri;
/**
* 是否获取unionId
*/
private boolean unionId;
/**
* Coding 企业名称
*/
private String codingGroupName;
/**
* 支付宝公钥
*/
private String alipayPublicKey;
/**
* 企业微信应用ID
*/
private String agentId;
/**
* stackoverflow api key
*/
private String stackOverflowKey;
/**
* 设备ID
*/
private String deviceId;
/**
* 客户端系统类型
*/
private String clientOsType;
/**
* maxkey 服务器地址
*/
private String serverUrl;
}

View File

@ -1,29 +0,0 @@
package org.dromara.common.social.config.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* Social 配置属性
*
* @author thiszhc
*/
@Data
@Component
@ConfigurationProperties(prefix = "justauth")
public class SocialProperties {
/**
* 是否启用
*/
private Boolean enabled;
/**
* 授权类型
*/
private Map<String, SocialLoginConfigProperties> type;
}

View File

@ -1,80 +0,0 @@
package org.dromara.common.social.maxkey;
import cn.hutool.core.lang.Dict;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthDefaultRequest;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.json.utils.JsonUtils;
/**
* @author 长春叭哥 2023年03月26日
*/
public class AuthMaxKeyRequest extends AuthDefaultRequest {
public static final String SERVER_URL = SpringUtils.getProperty("justauth.type.maxkey.server-url");
/**
* 设定归属域
*/
public AuthMaxKeyRequest(AuthConfig config) {
super(config, AuthMaxKeySource.MAXKEY);
}
public AuthMaxKeyRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthMaxKeySource.MAXKEY, authStateCache);
}
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
String body = doPostAuthorizationCode(authCallback.getCode());
Dict object = JsonUtils.parseMap(body);
// oauth/token 验证异常
if (object.containsKey("error")) {
throw new AuthException(object.getStr("error_description"));
}
// user 验证异常
if (object.containsKey("message")) {
throw new AuthException(object.getStr("message"));
}
return AuthToken.builder()
.accessToken(object.getStr("access_token"))
.refreshToken(object.getStr("refresh_token"))
.idToken(object.getStr("id_token"))
.tokenType(object.getStr("token_type"))
.scope(object.getStr("scope"))
.build();
}
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
String body = doGetUserInfo(authToken);
Dict object = JsonUtils.parseMap(body);
// oauth/token 验证异常
if (object.containsKey("error")) {
throw new AuthException(object.getStr("error_description"));
}
// user 验证异常
if (object.containsKey("message")) {
throw new AuthException(object.getStr("message"));
}
return AuthUser.builder()
.uuid(object.getStr("userId"))
.username(object.getStr("username"))
.nickname(object.getStr("displayName"))
.avatar(object.getStr("avatar_url"))
.blog(object.getStr("web_url"))
.company(object.getStr("organization"))
.location(object.getStr("location"))
.email(object.getStr("email"))
.remark(object.getStr("bio"))
.token(authToken)
.source(source.toString())
.build();
}
}

View File

@ -1,52 +0,0 @@
package org.dromara.common.social.maxkey;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.request.AuthDefaultRequest;
/**
* Oauth2 默认接口说明
*
* @author 长春叭哥 2023年03月26日
*
*/
public enum AuthMaxKeySource implements AuthSource {
/**
* 自己搭建的 maxkey 私服
*/
MAXKEY {
/**
* 授权的api
*/
@Override
public String authorize() {
return AuthMaxKeyRequest.SERVER_URL + "/sign/authz/oauth/v20/authorize";
}
/**
* 获取accessToken的api
*/
@Override
public String accessToken() {
return AuthMaxKeyRequest.SERVER_URL + "/sign/authz/oauth/v20/token";
}
/**
* 获取用户信息的api
*/
@Override
public String userInfo() {
return AuthMaxKeyRequest.SERVER_URL + "/sign/api/oauth/v20/me";
}
/**
* 平台对应的 AuthRequest 实现类必须继承自 {@link AuthDefaultRequest}
*/
@Override
public Class<? extends AuthDefaultRequest> getTargetClass() {
return AuthMaxKeyRequest.class;
}
}
}

View File

@ -1,61 +0,0 @@
package org.dromara.common.social.utils;
import lombok.AllArgsConstructor;
import me.zhyd.oauth.cache.AuthStateCache;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.redis.utils.RedisUtils;
import java.time.Duration;
/**
* 授权状态缓存
*/
@AllArgsConstructor
public class AuthRedisStateCache implements AuthStateCache {
/**
* 存入缓存
*
* @param key 缓存key
* @param value 缓存内容
*/
@Override
public void cache(String key, String value) {
// 授权超时时间 默认三分钟
RedisUtils.setCacheObject(GlobalConstants.SOCIAL_AUTH_CODE_KEY + key, value, Duration.ofMinutes(3));
}
/**
* 存入缓存
*
* @param key 缓存key
* @param value 缓存内容
* @param timeout 指定缓存过期时间(毫秒)
*/
@Override
public void cache(String key, String value, long timeout) {
RedisUtils.setCacheObject(GlobalConstants.SOCIAL_AUTH_CODE_KEY + key, value, Duration.ofMillis(timeout));
}
/**
* 获取缓存内容
*
* @param key 缓存key
* @return 缓存内容
*/
@Override
public String get(String key) {
return RedisUtils.getCacheObject(GlobalConstants.SOCIAL_AUTH_CODE_KEY + key);
}
/**
* 是否存在key如果对应key的value值已过期也返回false
*
* @param key 缓存key
* @return true存在key并且value没过期falsekey不存在或者已过期
*/
@Override
public boolean containsKey(String key) {
return RedisUtils.hasKey(GlobalConstants.SOCIAL_AUTH_CODE_KEY + key);
}
}

View File

@ -1,70 +0,0 @@
package org.dromara.common.social.utils;
import cn.hutool.core.util.ObjectUtil;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.*;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.social.config.properties.SocialLoginConfigProperties;
import org.dromara.common.social.config.properties.SocialProperties;
import org.dromara.common.social.maxkey.AuthMaxKeyRequest;
/**
* 认证授权工具类
*
* @author thiszhc
*/
public class SocialUtils {
private static final AuthRedisStateCache STATE_CACHE = SpringUtils.getBean(AuthRedisStateCache.class);
@SuppressWarnings("unchecked")
public static AuthResponse<AuthUser> loginAuth(String source, String code, String state, SocialProperties socialProperties) throws AuthException {
AuthRequest authRequest = getAuthRequest(source, socialProperties);
AuthCallback callback = new AuthCallback();
callback.setCode(code);
callback.setState(state);
return authRequest.login(callback);
}
public static AuthRequest getAuthRequest(String source, SocialProperties socialProperties) throws AuthException {
SocialLoginConfigProperties obj = socialProperties.getType().get(source);
if (ObjectUtil.isNull(obj)) {
throw new AuthException("不支持的第三方登录类型");
}
AuthConfig.AuthConfigBuilder builder = AuthConfig.builder()
.clientId(obj.getClientId())
.clientSecret(obj.getClientSecret())
.redirectUri(obj.getRedirectUri());
return switch (source.toLowerCase()) {
case "dingtalk" -> new AuthDingTalkRequest(builder.build(), STATE_CACHE);
case "baidu" -> new AuthBaiduRequest(builder.build(), STATE_CACHE);
case "github" -> new AuthGithubRequest(builder.build(), STATE_CACHE);
case "gitee" -> new AuthGiteeRequest(builder.build(), STATE_CACHE);
case "weibo" -> new AuthWeiboRequest(builder.build(), STATE_CACHE);
case "coding" -> new AuthCodingRequest(builder.build(), STATE_CACHE);
case "oschina" -> new AuthOschinaRequest(builder.build(), STATE_CACHE);
// 支付宝在创建回调地址时不允许使用localhost或者127.0.0.1所以这儿的回调地址使用的局域网内的ip
case "alipay_wallet" -> new AuthAlipayRequest(builder.build(), socialProperties.getType().get("alipay_wallet").getAlipayPublicKey(), STATE_CACHE);
case "qq" -> new AuthQqRequest(builder.build(), STATE_CACHE);
case "wechat_open" -> new AuthWeChatOpenRequest(builder.build(), STATE_CACHE);
case "taobao" -> new AuthTaobaoRequest(builder.build(), STATE_CACHE);
case "douyin" -> new AuthDouyinRequest(builder.build(), STATE_CACHE);
case "linkedin" -> new AuthLinkedinRequest(builder.build(), STATE_CACHE);
case "microsoft" -> new AuthMicrosoftRequest(builder.build(), STATE_CACHE);
case "renren" -> new AuthRenrenRequest(builder.build(), STATE_CACHE);
case "stack_overflow" -> new AuthStackOverflowRequest(builder.stackOverflowKey("").build(), STATE_CACHE);
case "huawei" -> new AuthHuaweiRequest(builder.build(), STATE_CACHE);
case "wechat_enterprise" -> new AuthWeChatEnterpriseQrcodeRequest(builder.agentId("").build(), STATE_CACHE);
case "gitlab" -> new AuthGitlabRequest(builder.build(), STATE_CACHE);
case "wechat_mp" -> new AuthWeChatMpRequest(builder.build(), STATE_CACHE);
case "aliyun" -> new AuthAliyunRequest(builder.build(), STATE_CACHE);
case "maxkey" -> new AuthMaxKeyRequest(builder.build(), STATE_CACHE);
default -> throw new AuthException("未获取到有效的Auth配置");
};
}
}

View File

@ -1,38 +0,0 @@
package org.dromara.system.controller.system;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.web.core.BaseController;
import org.dromara.system.domain.vo.SysSocialVo;
import org.dromara.system.service.ISysSocialService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 社会化关系
*
* @author thiszhc
* @date 2023-06-16
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/social")
public class SysSocialController extends BaseController {
private final ISysSocialService socialUserService;
/**
* 查询社会化关系列表
*/
@GetMapping("/list")
public R<List<SysSocialVo>> list() {
return R.ok(socialUserService.queryListByUserId(LoginHelper.getUserId()));
}
}

View File

@ -1,136 +0,0 @@
package org.dromara.system.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
/**
* 社会化关系对象 sys_social
*
* @author thiszhc
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_social")
public class SysSocial extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id")
private Long id;
/**
* 用户ID
*/
private Long userId;
/**
* 的唯一ID
*/
private String authId;
/**
* 用户来源
*/
private String source;
/**
* 用户的授权令牌
*/
private String accessToken;
/**
* 用户的授权令牌的有效期部分平台可能没有
*/
private int expireIn;
/**
* 刷新令牌部分平台可能没有
*/
private String refreshToken;
/**
* 用户的 open id
*/
private String openId;
/**
* 授权的第三方账号
*/
private String userName;
/**
* 授权的第三方昵称
*/
private String nickName;
/**
* 授权的第三方邮箱
*/
private String email;
/**
* 授权的第三方头像地址
*/
private String avatar;
/**
* 平台的授权信息部分平台可能没有
*/
private String accessCode;
/**
* 用户的 unionid
*/
private String unionId;
/**
* 授予的权限部分平台可能没有
*/
private String scope;
/**
* 个别平台的授权信息部分平台可能没有
*/
private String tokenType;
/**
* id token部分平台可能没有
*/
private String idToken;
/**
* 小米平台用户的附带属性部分平台可能没有
*/
private String macAlgorithm;
/**
* 小米平台用户的附带属性部分平台可能没有
*/
private String macKey;
/**
* 用户的授权code部分平台可能没有
*/
private String code;
/**
* Twitter平台用户的附带属性部分平台可能没有
*/
private String oauthToken;
/**
* Twitter平台用户的附带属性部分平台可能没有
*/
private String oauthTokenSecret;
}

View File

@ -1,142 +0,0 @@
package org.dromara.system.domain.bo;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.system.domain.SysSocial;
/**
* 社会化关系业务对象 sys_social
*
* @author Lion Li
*/
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = SysSocial.class, reverseConvertGenerate = false)
public class SysSocialBo extends BaseEntity {
/**
* 主键
*/
@NotNull(message = "主键不能为空", groups = { EditGroup.class })
private Long id;
/**
* 的唯一ID
*/
@NotBlank(message = "的唯一ID不能为空", groups = { AddGroup.class, EditGroup.class })
private String authId;
/**
* 用户来源
*/
@NotBlank(message = "用户来源不能为空", groups = { AddGroup.class, EditGroup.class })
private String source;
/**
* 用户的授权令牌
*/
@NotBlank(message = "用户的授权令牌不能为空", groups = { AddGroup.class, EditGroup.class })
private String accessToken;
/**
* 用户的授权令牌的有效期部分平台可能没有
*/
private int expireIn;
/**
* 刷新令牌部分平台可能没有
*/
private String refreshToken;
/**
* 平台唯一id
*/
private String openId;
/**
* 用户的 ID
*/
@NotBlank(message = "用户的 ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long userId;
/**
* 平台的授权信息部分平台可能没有
*/
private String accessCode;
/**
* 用户的 unionid
*/
private String unionId;
/**
* 授予的权限部分平台可能没有
*/
private String scope;
/**
* 授权的第三方账号
*/
private String userName;
/**
* 授权的第三方昵称
*/
private String nickName;
/**
* 授权的第三方邮箱
*/
private String email;
/**
* 授权的第三方头像地址
*/
private String avatar;
/**
* 个别平台的授权信息部分平台可能没有
*/
private String tokenType;
/**
* id token部分平台可能没有
*/
private String idToken;
/**
* 小米平台用户的附带属性部分平台可能没有
*/
private String macAlgorithm;
/**
* 小米平台用户的附带属性部分平台可能没有
*/
private String macKey;
/**
* 用户的授权code部分平台可能没有
*/
private String code;
/**
* Twitter平台用户的附带属性部分平台可能没有
*/
private String oauthToken;
/**
* Twitter平台用户的附带属性部分平台可能没有
*/
private String oauthTokenSecret;
}

View File

@ -1,144 +0,0 @@
package org.dromara.system.domain.vo;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.system.domain.SysSocial;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 社会化关系视图对象 sys_social
*
* @author thiszhc
*/
@Data
@AutoMapper(target = SysSocial.class)
public class SysSocialVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
private Long id;
/**
* 用户ID
*/
private Long userId;
/**
* 租户ID
*/
private String tenantId;
/**
* 的唯一ID
*/
private String authId;
/**
* 用户来源
*/
private String source;
/**
* 用户的授权令牌
*/
private String accessToken;
/**
* 用户的授权令牌的有效期部分平台可能没有
*/
private int expireIn;
/**
* 刷新令牌部分平台可能没有
*/
private String refreshToken;
/**
* 用户的 open id
*/
private String openId;
/**
* 授权的第三方账号
*/
private String userName;
/**
* 授权的第三方昵称
*/
private String nickName;
/**
* 授权的第三方邮箱
*/
private String email;
/**
* 授权的第三方头像地址
*/
private String avatar;
/**
* 平台的授权信息部分平台可能没有
*/
private String accessCode;
/**
* 用户的 unionid
*/
private String unionId;
/**
* 授予的权限部分平台可能没有
*/
private String scope;
/**
* 个别平台的授权信息部分平台可能没有
*/
private String tokenType;
/**
* id token部分平台可能没有
*/
private String idToken;
/**
* 小米平台用户的附带属性部分平台可能没有
*/
private String macAlgorithm;
/**
* 小米平台用户的附带属性部分平台可能没有
*/
private String macKey;
/**
* 用户的授权code部分平台可能没有
*/
private String code;
/**
* Twitter平台用户的附带属性部分平台可能没有
*/
private String oauthToken;
/**
* Twitter平台用户的附带属性部分平台可能没有
*/
private String oauthTokenSecret;
/**
* 创建时间
*/
private Date createTime;
}

View File

@ -1,14 +0,0 @@
package org.dromara.system.mapper;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.system.domain.SysSocial;
import org.dromara.system.domain.vo.SysSocialVo;
/**
* 社会化关系Mapper接口
*
* @author thiszhc
*/
public interface SysSocialMapper extends BaseMapperPlus<SysSocial, SysSocialVo> {
}

View File

@ -1,55 +0,0 @@
package org.dromara.system.service;
import org.dromara.system.domain.bo.SysSocialBo;
import org.dromara.system.domain.vo.SysSocialVo;
import java.util.List;
/**
* 社会化关系Service接口
*
* @author thiszhc
*/
public interface ISysSocialService {
/**
* 查询社会化关系
*/
SysSocialVo queryById(String id);
/**
* 查询社会化关系列表
*/
List<SysSocialVo> queryList();
/**
* 查询社会化关系列表
*/
List<SysSocialVo> queryListByUserId(Long userId);
/**
* 新增授权关系
*/
Boolean insertByBo(SysSocialBo bo);
/**
* 更新社会化关系
*/
Boolean updateByBo(SysSocialBo bo);
/**
* 删除社会化关系信息
*/
Boolean deleteWithValidById(Long id);
/**
* 根据 authId 查询 SysSocial 表和 SysUser 返回 SysSocialAuthResult 映射的对象
* @param authId 认证ID
* @return SysSocial
*/
List<SysSocialVo> selectByAuthId(String authId);
}

View File

@ -1,106 +0,0 @@
package org.dromara.system.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.system.domain.SysSocial;
import org.dromara.system.domain.bo.SysSocialBo;
import org.dromara.system.domain.vo.SysSocialVo;
import org.dromara.system.mapper.SysSocialMapper;
import org.dromara.system.service.ISysSocialService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 社会化关系Service业务层处理
*
* @author thiszhc
* @date 2023-06-12
*/
@RequiredArgsConstructor
@Service
public class SysSocialServiceImpl implements ISysSocialService {
private final SysSocialMapper baseMapper;
/**
* 查询社会化关系
*/
@Override
public SysSocialVo queryById(String id) {
return baseMapper.selectVoById(id);
}
/**
* 授权列表
*/
@Override
public List<SysSocialVo> queryList() {
return baseMapper.selectVoList();
}
@Override
public List<SysSocialVo> queryListByUserId(Long userId) {
return baseMapper.selectVoList(new LambdaQueryWrapper<SysSocial>().eq(SysSocial::getUserId, userId));
}
/**
* 新增社会化关系
*/
@Override
public Boolean insertByBo(SysSocialBo bo) {
SysSocial add = MapstructUtils.convert(bo, SysSocial.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
if (add != null) {
bo.setId(add.getId());
} else {
return false;
}
}
return flag;
}
/**
* 更新社会化关系
*/
@Override
public Boolean updateByBo(SysSocialBo bo) {
SysSocial update = MapstructUtils.convert(bo, SysSocial.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(SysSocial entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* 删除社会化关系
*/
@Override
public Boolean deleteWithValidById(Long id) {
return baseMapper.deleteById(id) > 0;
}
/**
* 根据 authId 查询用户信息
*
* @param authId 认证id
* @return 授权信息
*/
@Override
public List<SysSocialVo> selectByAuthId(String authId) {
return baseMapper.selectVoList(new LambdaQueryWrapper<SysSocial>().eq(SysSocial::getAuthId, authId));
}
}

View File

@ -4,35 +4,29 @@ import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.util.ObjectUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.dromara.common.core.constant.UserConstants;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.LoginBody;
import org.dromara.common.core.domain.model.RegisterBody;
import org.dromara.common.core.domain.model.SocialLoginBody;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.common.encrypt.annotation.ApiEncrypt;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.social.config.properties.SocialLoginConfigProperties;
import org.dromara.common.social.config.properties.SocialProperties;
import org.dromara.common.social.utils.SocialUtils;
import org.dromara.common.websocket.utils.WebSocketUtils;
import org.dromara.system.domain.SysClient;
import org.dromara.system.service.ISysClientService;
import org.dromara.system.service.ISysConfigService;
import org.dromara.system.service.ISysSocialService;
import org.dromara.web.domain.vo.LoginVo;
import org.dromara.web.service.IAuthStrategy;
import org.dromara.web.service.SysLoginService;
import org.dromara.web.service.SysRegisterService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -49,11 +43,9 @@ import java.util.concurrent.TimeUnit;
@RequestMapping("/auth")
public class AuthController {
private final SocialProperties socialProperties;
private final SysLoginService loginService;
private final SysRegisterService registerService;
private final ISysConfigService configService;
private final ISysSocialService socialUserService;
private final ISysClientService clientService;
private final ScheduledExecutorService scheduledExecutorService;
@ -90,57 +82,6 @@ public class AuthController {
return R.ok(loginVo);
}
/**
* 第三方登录请求
*
* @param source 登录来源
* @return 结果
*/
@GetMapping("/binding/{source}")
public R<String> authBinding(@PathVariable("source") String source) {
SocialLoginConfigProperties obj = socialProperties.getType().get(source);
if (ObjectUtil.isNull(obj)) {
return R.fail(source + "平台账号暂不支持");
}
AuthRequest authRequest = SocialUtils.getAuthRequest(source, socialProperties);
String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
return R.ok("操作成功", authorizeUrl);
}
/**
* 第三方登录回调业务处理 绑定授权
*
* @param loginBody 请求体
* @return 结果
*/
@PostMapping("/social/callback")
public R<Void> socialCallback(@RequestBody SocialLoginBody loginBody) {
// 获取第三方登录信息
AuthResponse<AuthUser> response = SocialUtils.loginAuth(
loginBody.getSource(), loginBody.getSocialCode(),
loginBody.getSocialState(), socialProperties);
AuthUser authUserData = response.getData();
// 判断授权响应是否成功
if (!response.ok()) {
return R.fail(response.getMsg());
}
loginService.socialRegister(authUserData);
return R.ok();
}
/**
* 取消授权
*
* @param socialId socialId
*/
@DeleteMapping(value = "/unlock/{socialId}")
public R<Void> unlockSocial(@PathVariable Long socialId) {
Boolean rows = socialUserService.deleteWithValidById(socialId);
return rows ? R.ok() : R.fail("取消授权失败");
}
/**
* 退出登录
*/

View File

@ -3,11 +3,9 @@ package org.dromara.web.service;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthUser;
import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.domain.dto.RoleDTO;
@ -23,12 +21,9 @@ import org.dromara.common.mybatis.helper.DataPermissionHelper;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.bo.SysSocialBo;
import org.dromara.system.domain.vo.SysSocialVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.service.ISysPermissionService;
import org.dromara.system.service.ISysSocialService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@ -53,39 +48,9 @@ public class SysLoginService {
private Integer lockTime;
private final ISysPermissionService permissionService;
private final ISysSocialService sysSocialService;
private final SysUserMapper userMapper;
/**
* 绑定第三方用户
*
* @param authUserData 授权响应实体
* @return 统一响应实体
*/
public void socialRegister(AuthUser authUserData) {
String authId = authUserData.getSource() + authUserData.getUuid();
// 第三方用户信息
SysSocialBo bo = BeanUtil.toBean(authUserData, SysSocialBo.class);
BeanUtil.copyProperties(authUserData.getToken(), bo);
bo.setUserId(LoginHelper.getUserId());
bo.setAuthId(authId);
bo.setOpenId(authUserData.getUuid());
bo.setUserName(authUserData.getUsername());
bo.setNickName(authUserData.getNickname());
// 查询是否已经绑定用户
List<SysSocialVo> list = sysSocialService.selectByAuthId(authId);
if (CollUtil.isEmpty(list)) {
// 没有绑定用户, 新增用户信息
sysSocialService.insertByBo(bo);
} else {
// 更新用户信息
bo.setId(list.get(0).getId());
sysSocialService.updateByBo(bo);
}
}
/**
* 退出登录
*/

View File

@ -1,128 +0,0 @@
package org.dromara.web.service.impl;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.domain.model.SocialLoginBody;
import org.dromara.common.core.enums.UserStatus;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.exception.user.UserException;
import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.social.config.properties.SocialProperties;
import org.dromara.common.social.utils.SocialUtils;
import org.dromara.system.domain.SysClient;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.vo.SysSocialVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.service.ISysSocialService;
import org.dromara.web.domain.vo.LoginVo;
import org.dromara.web.service.IAuthStrategy;
import org.dromara.web.service.SysLoginService;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
/**
* 第三方授权策略
*
* @author thiszhc is 三三
*/
@Slf4j
@Service("social" + IAuthStrategy.BASE_NAME)
@RequiredArgsConstructor
public class SocialAuthStrategy implements IAuthStrategy {
private final SocialProperties socialProperties;
private final ISysSocialService sysSocialService;
private final SysUserMapper userMapper;
private final SysLoginService loginService;
/**
* 登录-第三方授权登录
*
* @param body 登录信息
* @param client 客户端信息
*/
@Override
public LoginVo login(String body, SysClient client) {
SocialLoginBody loginBody = JsonUtils.parseObject(body, SocialLoginBody.class);
ValidatorUtils.validate(loginBody);
AuthResponse<AuthUser> response = SocialUtils.loginAuth(
loginBody.getSource(), loginBody.getSocialCode(),
loginBody.getSocialState(), socialProperties);
if (!response.ok()) {
throw new ServiceException(response.getMsg());
}
AuthUser authUserData = response.getData();
if ("GITEE".equals(authUserData.getSource())) {
// 如用户使用 gitee 登录顺手 star 给作者一点支持 拒绝白嫖
HttpUtil.createRequest(Method.PUT, "https://gitee.com/api/v5/user/starred/dromara/RuoYi-Vue-Plus")
.formStr(MapUtil.of("access_token", authUserData.getToken().getAccessToken()))
.executeAsync();
HttpUtil.createRequest(Method.PUT, "https://gitee.com/api/v5/user/starred/dromara/RuoYi-Cloud-Plus")
.formStr(MapUtil.of("access_token", authUserData.getToken().getAccessToken()))
.executeAsync();
}
List<SysSocialVo> list = sysSocialService.selectByAuthId(authUserData.getSource() + authUserData.getUuid());
if (CollUtil.isEmpty(list)) {
throw new ServiceException("你还没有绑定第三方账号,绑定后才可以登录!");
}
Optional<SysSocialVo> opt = list.stream().filter(x -> x.getTenantId().equals(loginBody.getTenantId())).findAny();
if (opt.isEmpty()) {
throw new ServiceException("对不起,你没有权限登录当前租户!");
}
SysSocialVo social = opt.get();
// 查找用户
SysUserVo user = loadUser(social.getTenantId(), social.getUserId());
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
LoginUser loginUser = loginService.buildLoginUser(user);
loginUser.setClientKey(client.getClientKey());
loginUser.setDeviceType(client.getDeviceType());
SaLoginModel model = new SaLoginModel();
model.setDevice(client.getDeviceType());
// 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
// 例如: 后台用户30分钟过期 app用户1天过期
model.setTimeout(client.getTimeout());
model.setActiveTimeout(client.getActiveTimeout());
model.setExtra(LoginHelper.CLIENT_KEY, client.getClientId());
// 生成token
LoginHelper.login(loginUser, model);
LoginVo loginVo = new LoginVo();
loginVo.setAccessToken(StpUtil.getTokenValue());
loginVo.setExpireIn(StpUtil.getTokenTimeout());
loginVo.setClientId(client.getClientId());
return loginVo;
}
private SysUserVo loadUser(String tenantId, Long userId) {
SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
.select(SysUser::getUserName, SysUser::getStatus)
.eq(SysUser::getUserId, userId));
if (ObjectUtil.isNull(user)) {
log.info("登录用户:{} 不存在.", "");
throw new UserException("user.not.exists", "");
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
log.info("登录用户:{} 已被停用.", "");
throw new UserException("user.blocked", "");
}
return userMapper.selectUserByUserName(user.getUserName());
}
}

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.system.mapper.SysSocialMapper">
</mapper>