Commit a56b4a7c9c6b1d4363a65dd87c1c2fd112d25d75

Authored by YunaiV
1 parent 23888c5a

增加三方登陆的 redirect uri

Showing 22 changed files with 258 additions and 840 deletions
yudao-admin-server/pom.xml
... ... @@ -117,6 +117,12 @@
117 117 <artifactId>screw-core</artifactId> <!-- 实现数据库文档 -->
118 118 </dependency>
119 119  
  120 + <!-- TODO 后续看情况,进行调整 -->
  121 + <dependency>
  122 + <groupId>com.xkcoding.justauth</groupId>
  123 + <artifactId>justauth-spring-boot-starter</artifactId>
  124 + <version>1.4.0</version>
  125 + </dependency>
120 126 </dependencies>
121 127  
122 128 <build>
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/infra/controller/file/InfFileController.java
... ... @@ -41,7 +41,7 @@ public class InfFileController {
41 41 @ApiOperation("上传文件")
42 42 @ApiImplicitParams({
43 43 @ApiImplicitParam(name = "file", value = "文件附件", required = true, dataTypeClass = MultipartFile.class),
44   - @ApiImplicitParam(name = "path", value = "文件路径", required = false, example = "yudaoyuanma.png", dataTypeClass = String.class)
  44 + @ApiImplicitParam(name = "path", value = "文件路径", example = "yudaoyuanma.png", dataTypeClass = String.class)
45 45 })
46 46 public CommonResult<String> uploadFile(@RequestParam("file") MultipartFile file,
47 47 @RequestParam("path") String path) throws IOException {
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.java
1 1 package cn.iocoder.yudao.adminserver.modules.system.controller.auth;
2 2  
  3 +import cn.hutool.core.net.url.UrlBuilder;
  4 +import cn.hutool.http.HttpUtil;
  5 +import cn.hutool.json.JSONUtil;
  6 +import cn.iocoder.yudao.adminserver.modules.system.enums.user.SysUserSocialTypeEnum;
3 7 import cn.iocoder.yudao.adminserver.modules.system.service.auth.SysUserSessionService;
4 8 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
5 9 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  10 +import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
6 11 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
7 12 import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthLoginReqVO;
8 13 import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthLoginRespVO;
... ... @@ -18,15 +23,31 @@ import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermiss
18 23 import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysRoleService;
19 24 import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
20 25 import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
  26 +import com.aliyuncs.CommonResponse;
  27 +import com.xkcoding.justauth.AuthRequestFactory;
21 28 import io.swagger.annotations.Api;
  29 +import io.swagger.annotations.ApiImplicitParam;
  30 +import io.swagger.annotations.ApiImplicitParams;
22 31 import io.swagger.annotations.ApiOperation;
23   -import org.springframework.security.core.Authentication;
24   -import org.springframework.security.core.context.SecurityContextHolder;
  32 +import lombok.extern.slf4j.Slf4j;
  33 +import me.zhyd.oauth.model.AuthCallback;
  34 +import me.zhyd.oauth.model.AuthResponse;
  35 +import me.zhyd.oauth.model.AuthUser;
  36 +import me.zhyd.oauth.request.AuthRequest;
  37 +import me.zhyd.oauth.utils.AuthStateUtils;
  38 +import org.apache.commons.lang.StringUtils;
  39 +import org.quartz.SimpleTrigger;
25 40 import org.springframework.validation.annotation.Validated;
26 41 import org.springframework.web.bind.annotation.*;
  42 +import org.springframework.web.multipart.MultipartFile;
  43 +import org.springframework.web.util.UriBuilder;
27 44  
28 45 import javax.annotation.Resource;
  46 +import javax.servlet.http.HttpServletResponse;
29 47 import javax.validation.Valid;
  48 +import java.io.IOException;
  49 +import java.net.URL;
  50 +import java.nio.charset.Charset;
30 51 import java.util.List;
31 52  
32 53 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
... ... @@ -39,6 +60,7 @@ import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getUse
39 60 @RestController
40 61 @RequestMapping("/")
41 62 @Validated
  63 +@Slf4j
42 64 public class SysAuthController {
43 65  
44 66 @Resource
... ... @@ -52,6 +74,9 @@ public class SysAuthController {
52 74 @Resource
53 75 private SysUserSessionService sysUserSessionService;
54 76  
  77 + @Resource
  78 + private AuthRequestFactory authRequestFactory;
  79 +
55 80 @PostMapping("/login")
56 81 @ApiOperation("使用账号密码登录")
57 82 @OperateLog(enable = false) // 避免 Post 请求被记录操作日志
... ... @@ -61,17 +86,42 @@ public class SysAuthController {
61 86 return success(SysAuthLoginRespVO.builder().token(token).build());
62 87 }
63 88  
64   - @RequestMapping("/auth2/login/{oauthType}")
65   - @ApiOperation("第三方登录")
66   - @OperateLog(enable = false) // 避免 Post 请求被记录操作日志
67   - public CommonResult<SysAuthLoginRespVO> login(@PathVariable String oauthType) {
68   - Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
69   - //TODO NPE
70   - String token = sysUserSessionService.getSessionId(authentication.getName());
71   - // 返回结果
72   - return success(SysAuthLoginRespVO.builder().token(token).build());
  89 + @GetMapping("/third-login-redirect")
  90 + @ApiOperation("三方登陆的跳转")
  91 + @ApiImplicitParams({
  92 + @ApiImplicitParam(name = "type", value = "三方类型", required = true, dataTypeClass = Integer.class),
  93 + @ApiImplicitParam(name = "redirectUri", value = "回调路径", dataTypeClass = String.class)
  94 + })
  95 + public CommonResult<String> login(@RequestParam("type") Integer type,
  96 + @RequestParam("redirectUri") String redirectUri) throws IOException {
  97 + // 获得对应的 AuthRequest 实现
  98 + AuthRequest authRequest = authRequestFactory.get(SysUserSocialTypeEnum.valueOfType(type).getSource());
  99 + // 生成跳转地址
  100 + String authorizeUri = authRequest.authorize(AuthStateUtils.createState());
  101 + authorizeUri = HttpUtils.replaceUrlQuery(authorizeUri, "redirect_uri", redirectUri);
  102 +// authorizeUri = UrlBuilder.fromBaseUrl(authorizeUri).queryParam("redirect_uri", redirectUri).build();
  103 + return CommonResult.success(authorizeUri);
  104 + }
  105 +
  106 + @RequestMapping("/{type}/callback")
  107 + public AuthResponse login(@PathVariable String type, AuthCallback callback) {
  108 + AuthRequest authRequest = authRequestFactory.get(type);
  109 + AuthResponse<AuthUser> response = authRequest.login(callback);
  110 + log.info("【response】= {}", JSONUtil.toJsonStr(response));
  111 + return response;
73 112 }
74 113  
  114 +// @RequestMapping("/auth2/login/{oauthType}")
  115 +// @ApiOperation("第三方登录")
  116 +// @OperateLog(enable = false) // 避免 Post 请求被记录操作日志
  117 +// public CommonResult<SysAuthLoginRespVO> login(@PathVariable String oauthType) {
  118 +// Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
  119 +// //TODO NPE
  120 +// String token = sysUserSessionService.getSessionId(authentication.getName());
  121 +// // 返回结果
  122 +// return success(SysAuthLoginRespVO.builder().token(token).build());
  123 +// }
  124 +
75 125 @GetMapping("/get-permission-info")
76 126 @ApiOperation("获取登陆用户的权限信息")
77 127 public CommonResult<SysAuthPermissionInfoRespVO> getPermissionInfo() {
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/convert/auth/SysAuthConvert.java
1 1 package cn.iocoder.yudao.adminserver.modules.system.convert.auth;
2 2  
3   -import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user.SysUserCreateReqVO;
4   -import cn.iocoder.yudao.adminserver.modules.system.enums.common.SysSexEnum;
5   -import cn.iocoder.yudao.framework.security.core.Auth2LoginUser;
6   -import cn.iocoder.yudao.framework.security.core.LoginUser;
7 3 import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthMenuRespVO;
8 4 import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthPermissionInfoRespVO;
9 5 import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO;
10 6 import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO;
  7 +import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user.SysUserCreateReqVO;
11 8 import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.permission.SysMenuDO;
12 9 import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.permission.SysRoleDO;
13 10 import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO;
14 11 import cn.iocoder.yudao.adminserver.modules.system.enums.permission.MenuIdEnum;
15 12 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
16   -import me.zhyd.oauth.enums.AuthUserGender;
  13 +import cn.iocoder.yudao.framework.security.core.LoginUser;
17 14 import me.zhyd.oauth.model.AuthUser;
18   -import org.mapstruct.*;
  15 +import org.mapstruct.Mapper;
  16 +import org.mapstruct.Mapping;
  17 +import org.mapstruct.Mappings;
19 18 import org.mapstruct.factory.Mappers;
20 19 import org.slf4j.LoggerFactory;
21 20  
22   -import java.util.ArrayList;
23   -import java.util.Comparator;
24   -import java.util.LinkedHashMap;
25   -import java.util.List;
26   -import java.util.Map;
  21 +import java.util.*;
27 22  
28   -@Mapper(uses = SysAuthConvert.UserSexTransform.class)
  23 +@Mapper
29 24 public interface SysAuthConvert {
30 25  
31 26 SysAuthConvert INSTANCE = Mappers.getMapper(SysAuthConvert.class);
... ... @@ -33,7 +28,6 @@ public interface SysAuthConvert {
33 28 @Mapping(source = "updateTime", target = "updateTime", ignore = true)
34 29 // 字段相同,但是含义不同,忽略
35 30 LoginUser convert(SysUserDO bean);
36   - Auth2LoginUser getAuth2LoginUser(SysUserDO bean);
37 31  
38 32 default SysAuthPermissionInfoRespVO convert(SysUserDO user, List<SysRoleDO> roleList, List<SysMenuDO> menuList) {
39 33 return SysAuthPermissionInfoRespVO.builder()
... ... @@ -49,16 +43,6 @@ public interface SysAuthConvert {
49 43  
50 44 LoginUser convert(SysUserProfileUpdatePasswordReqVO reqVO);
51 45  
52   - @Mappings(
53   - @Mapping(target = "sex", source = "gender")
54   - )
55   - SysUserCreateReqVO convert(AuthUser authUser);
56   -
57   - @Mappings(
58   - @Mapping(target = "thirdPartyUserId", source = "uuid")
59   - )
60   - Auth2LoginUser getLoginUser(AuthUser authUser);
61   -
62 46 /**
63 47 * 将菜单列表,构建成菜单树
64 48 *
... ... @@ -91,24 +75,4 @@ public interface SysAuthConvert {
91 75 return CollectionUtils.filterList(treeNodeMap.values(), node -> MenuIdEnum.ROOT.getId().equals(node.getParentId()));
92 76 }
93 77  
94   - public class UserSexTransform {
95   -
96   - public int toInt (AuthUserGender gender){
97   - switch (gender) {
98   - case MALE:
99   - return SysSexEnum.MALE.getSex();
100   - case FEMALE:
101   - return SysSexEnum.FEMALE.getSex();
102   - default:
103   - return SysSexEnum.UNKNOWN.getSex();
104   - }
105   - }
106   -
107   - public AuthUserGender strToBoolean(int sex){
108   - if(sex == SysSexEnum.UNKNOWN.getSex()) {
109   - return AuthUserGender.UNKNOWN;
110   - }
111   - return AuthUserGender.getRealGender(String.valueOf(sex));
112   - }
113   - }
114 78 }
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/convert/auth/config/AuthConfig.java deleted
1   -package cn.iocoder.yudao.adminserver.modules.system.convert.auth.config;
2   -
3   -import cn.iocoder.yudao.adminserver.modules.system.convert.auth.handler.DefaultSignUpUrlAuthenticationSuccessHandler;
4   -import cn.iocoder.yudao.framework.security.core.handler.AbstractSignUpUrlAuthenticationSuccessHandler;
5   -import org.springframework.context.annotation.Bean;
6   -import org.springframework.context.annotation.Configuration;
7   -
8   -/**
9   - * @author weir
10   - */
11   -@Configuration
12   -public class AuthConfig {
13   - @Bean
14   - public AbstractSignUpUrlAuthenticationSuccessHandler authenticationSuccessHandler() {
15   - AbstractSignUpUrlAuthenticationSuccessHandler successHandler = new DefaultSignUpUrlAuthenticationSuccessHandler();
16   - successHandler.setDefaultTargetUrl("/api/callback");
17   - return successHandler;
18   - }
19   -}
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/convert/auth/handler/DefaultSignUpUrlAuthenticationSuccessHandler.java deleted
1   -/*
2   - * MIT License
3   - * Copyright (c) 2020-2029 YongWu zheng (dcenter.top and gitee.com/pcore and github.com/ZeroOrInfinity)
4   - *
5   - * Permission is hereby granted, free of charge, to any person obtaining a copy
6   - * of this software and associated documentation files (the "Software"), to deal
7   - * in the Software without restriction, including without limitation the rights
8   - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9   - * copies of the Software, and to permit persons to whom the Software is
10   - * furnished to do so, subject to the following conditions:
11   - *
12   - * The above copyright notice and this permission notice shall be included in all
13   - * copies or substantial portions of the Software.
14   - *
15   - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16   - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17   - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18   - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19   - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20   - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21   - * SOFTWARE.
22   - */
23   -package cn.iocoder.yudao.adminserver.modules.system.convert.auth.handler;
24   -
25   -import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthLoginRespVO;
26   -import cn.iocoder.yudao.adminserver.modules.system.service.auth.SysUserSessionService;
27   -import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
28   -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
29   -import cn.iocoder.yudao.framework.security.core.Auth2LoginUser;
30   -import cn.iocoder.yudao.framework.security.core.LoginUser;
31   -import cn.iocoder.yudao.framework.security.core.handler.AbstractSignUpUrlAuthenticationSuccessHandler;
32   -import org.apache.commons.lang3.StringUtils;
33   -import org.springframework.beans.factory.annotation.Autowired;
34   -import org.springframework.http.HttpStatus;
35   -import org.springframework.security.core.Authentication;
36   -import org.springframework.security.core.context.SecurityContextHolder;
37   -import org.springframework.security.web.DefaultRedirectStrategy;
38   -import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
39   -import org.springframework.security.web.savedrequest.RequestCache;
40   -
41   -import javax.annotation.Resource;
42   -import javax.servlet.ServletException;
43   -import javax.servlet.http.HttpServletRequest;
44   -import javax.servlet.http.HttpServletResponse;
45   -import java.io.IOException;
46   -import java.util.Set;
47   -
48   -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
49   -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
50   -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getUserAgent;
51   -import static java.util.Collections.singleton;
52   -import static top.dcenter.ums.security.core.oauth.util.MvcUtil.*;
53   -
54   -/**
55   - * @author weir
56   - */
57   -public class DefaultSignUpUrlAuthenticationSuccessHandler extends AbstractSignUpUrlAuthenticationSuccessHandler {
58   - private RequestCache requestCache = new HttpSessionRequestCache();
59   - @Autowired
60   - private SysUserSessionService userSessionService;
61   - @Resource
62   - private SysPermissionService permissionService;
63   -
64   - @Override
65   - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
66   - final Object principal = authentication.getPrincipal();
67   - String token = userSessionService.createUserSession(defaultHandleUserRoles((LoginUser) principal), getClientIP(), getUserAgent());
68   - if(StringUtils.isNotBlank(token)) {
69   - SecurityContextHolder.getContext().setAuthentication(authentication);
70   - }
71   - if (principal instanceof Auth2LoginUser) {
72   - new DefaultRedirectStrategy().sendRedirect(request, response, getUrl() + token);
73   - return;
74   - }
75   - if (isAjaxOrJson(request)) {
76   - responseWithJson(response, HttpStatus.OK.value(), toJsonString(success(SysAuthLoginRespVO.builder().token(token).build())));
77   - return;
78   - }
79   - try {
80   - requestCache.saveRequest(request, response);
81   - super.setRequestCache(requestCache);
82   - super.onAuthenticationSuccess(request, response, authentication);
83   - } catch (ServletException e) {
84   - e.printStackTrace();
85   - }
86   -
87   - }
88   -
89   - private String getUrl() {
90   -// return "http://localhost/oauthLogin/gitee?token=";
91   - return "http://127.0.0.1:1024/oauthLogin/gitee?token=";
92   - }
93   -
94   - /**
95   - * 默认处理方式处理用户角色列表;建议角色权限前置到 UserDetails
96   - *
97   - * @param loginUser 用户
98   - * @return
99   - */
100   - private LoginUser defaultHandleUserRoles(LoginUser loginUser) {
101   - Set<Long> roleIds = loginUser.getRoleIds();
102   - if (roleIds == null || roleIds.isEmpty()) {
103   - Set<Long> userRoleIds = permissionService.getUserRoleIds(loginUser.getId(), singleton(CommonStatusEnum.ENABLE.getStatus()));
104   - loginUser.setRoleIds(userRoleIds);
105   - }
106   - return loginUser;
107   - }
108   -
109   - @Override
110   - public void setRequestCache(RequestCache requestCache) {
111   - this.requestCache = requestCache;
112   - }
113   -}
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/social/SocialUserDO.java deleted
1   -package cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.social;
2   -
3   -import com.baomidou.mybatisplus.annotation.TableName;
4   -import lombok.Data;
5   -import me.zhyd.oauth.model.AuthUser;
6   -
7   -/**
8   - * @author weir
9   - */
10   -@Data
11   -@TableName("user_connection")
12   -public class SocialUserDO extends AuthUser {
13   -}
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/social/SysUserSocialDO.java deleted
1   -package cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.social;
2   -
3   -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4   -import com.baomidou.mybatisplus.annotation.TableId;
5   -import com.baomidou.mybatisplus.annotation.TableName;
6   -import lombok.Data;
7   -import lombok.EqualsAndHashCode;
8   -
9   -/**
10   - * 系统用户和第三方用户关联表
11   - * @author weir
12   - */
13   -@TableName("sys_user_social")
14   -@Data
15   -public class SysUserSocialDO extends BaseDO {
16   - /**
17   - * 自增主键
18   - */
19   - @TableId
20   - private Long id;
21   - /**
22   - * 用户 ID
23   - */
24   - private Long userId;
25   - /**
26   - * 角色 ID
27   - */
28   - private String socialUserId;
29   -}
30   -
31   -
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/user/SysUserSocialDO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.system.enums.user.SysUserSocialTypeEnum;
  4 +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
  5 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  6 +import com.baomidou.mybatisplus.annotation.TableId;
  7 +import com.baomidou.mybatisplus.annotation.TableName;
  8 +import lombok.*;
  9 +
  10 +/**
  11 + * 三方登陆信息
  12 + * 通过 {@link SysUserSocialDO#getUserId()} 关联到对应的 {@link SysUserDO}
  13 + *
  14 + * @author weir
  15 + */
  16 +@TableName(value = "sys_user_social", autoResultMap = true)
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@Builder
  20 +@NoArgsConstructor
  21 +@AllArgsConstructor
  22 +public class SysUserSocialDO extends BaseDO {
  23 +
  24 + /**
  25 + * 自增主键
  26 + */
  27 + @TableId
  28 + private Long id;
  29 + /**
  30 + * 用户编号
  31 + */
  32 + private Long userId;
  33 + /**
  34 + * 用户类型
  35 + *
  36 + * 枚举 {@link UserTypeEnum}
  37 + */
  38 + private Integer userType;
  39 +
  40 + /**
  41 + * 三方平台的类型
  42 + */
  43 + private SysUserSocialTypeEnum type;
  44 + /**
  45 + * 三方 openid
  46 + */
  47 + private String openid;
  48 + /**
  49 + * 三方 token
  50 + */
  51 + private String token;
  52 + /**
  53 + * 三方的全局编号
  54 + *
  55 + * 例如说,微信平台的 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/union-id.html
  56 + * 如果没有 unionId 的平台,直接使用 openid 作为该字段的值
  57 + */
  58 + private String unionId;
  59 +
  60 + /**
  61 + * 用户昵称
  62 + */
  63 + private String nickname;
  64 + /**
  65 + * 用户头像
  66 + */
  67 + private String avatar;
  68 + /**
  69 + * 原始数据,一般是 JSON 格式
  70 + */
  71 + private String info;
  72 +
  73 +}
  74 +
  75 +
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/social/SysSysUserSocialMapper.java
1 1 package cn.iocoder.yudao.adminserver.modules.system.dal.mysql.social;
2 2  
3   -import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.social.SysUserSocialDO;
  3 +import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserSocialDO;
4 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 5 import org.apache.ibatis.annotations.Mapper;
6 6  
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/social/SysUserSocialMapper.java
1 1 package cn.iocoder.yudao.adminserver.modules.system.dal.mysql.social;
2 2  
3   -import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.social.SysUserSocialDO;
  3 +import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserSocialDO;
4 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 5 import org.apache.ibatis.annotations.Mapper;
6 6  
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/user/SysUserSocialTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.system.enums.user;
  2 +
  3 +import cn.hutool.core.util.ArrayUtil;
  4 +import cn.iocoder.yudao.adminserver.modules.system.enums.errorcode.SysErrorCodeTypeEnum;
  5 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  6 +import jodd.util.ArraysUtil;
  7 +import lombok.AllArgsConstructor;
  8 +import lombok.Getter;
  9 +
  10 +import java.util.Arrays;
  11 +
  12 +/**
  13 + * 用户的三方平台的类型枚举
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Getter
  18 +@AllArgsConstructor
  19 +public enum SysUserSocialTypeEnum implements IntArrayValuable {
  20 +
  21 + GITEE(10, "GITEE"), // https://gitee.com/api/v5/oauth_doc#/
  22 + ;
  23 +
  24 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SysUserSocialTypeEnum::getType).toArray();
  25 +
  26 + /**
  27 + * 类型
  28 + */
  29 + private final Integer type;
  30 + /**
  31 + * 类型的标识
  32 + */
  33 + private final String source;
  34 +
  35 + @Override
  36 + public int[] array() {
  37 + return ARRAYS;
  38 + }
  39 +
  40 + public static SysUserSocialTypeEnum valueOfType(Integer type) {
  41 + return ArrayUtil.firstMatch(o -> o.getType().equals(type), values());
  42 + }
  43 +
  44 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/UserDetailsServiceImpl.java deleted
1   -/*
2   - * MIT License
3   - * Copyright (c) 2020-2029 YongWu zheng (dcenter.top and gitee.com/pcore and github.com/ZeroOrInfinity)
4   - *
5   - * Permission is hereby granted, free of charge, to any person obtaining a copy
6   - * of this software and associated documentation files (the "Software"), to deal
7   - * in the Software without restriction, including without limitation the rights
8   - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9   - * copies of the Software, and to permit persons to whom the Software is
10   - * furnished to do so, subject to the following conditions:
11   - *
12   - * The above copyright notice and this permission notice shall be included in all
13   - * copies or substantial portions of the Software.
14   - *
15   - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16   - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17   - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18   - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19   - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20   - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21   - * SOFTWARE.
22   - */
23   -
24   -package cn.iocoder.yudao.adminserver.modules.system.service.auth.impl;
25   -
26   -import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user.SysUserCreateReqVO;
27   -import cn.iocoder.yudao.adminserver.modules.system.convert.auth.SysAuthConvert;
28   -import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO;
29   -import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
30   -import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
31   -import cn.iocoder.yudao.framework.security.core.Auth2LoginUser;
32   -import cn.iocoder.yudao.framework.security.core.LoginUser;
33   -import com.google.common.collect.Sets;
34   -import me.zhyd.oauth.model.AuthUser;
35   -import org.apache.commons.lang3.StringUtils;
36   -import org.slf4j.Logger;
37   -import org.slf4j.LoggerFactory;
38   -import org.springframework.beans.factory.annotation.Autowired;
39   -import org.springframework.lang.NonNull;
40   -import org.springframework.security.core.authority.AuthorityUtils;
41   -import org.springframework.security.core.userdetails.User;
42   -import org.springframework.security.core.userdetails.UserCache;
43   -import org.springframework.security.core.userdetails.UserDetails;
44   -import org.springframework.security.core.userdetails.UsernameNotFoundException;
45   -import org.springframework.security.crypto.password.PasswordEncoder;
46   -import org.springframework.stereotype.Service;
47   -import org.springframework.web.context.request.RequestAttributes;
48   -import org.springframework.web.context.request.RequestContextHolder;
49   -import top.dcenter.ums.security.core.oauth.enums.ErrorCodeEnum;
50   -import top.dcenter.ums.security.core.oauth.exception.RegisterUserFailureException;
51   -import top.dcenter.ums.security.core.oauth.exception.UserNotExistException;
52   -import top.dcenter.ums.security.core.oauth.service.UmsUserDetailsService;
53   -
54   -import javax.annotation.Resource;
55   -import java.util.ArrayList;
56   -import java.util.List;
57   -import java.util.Map;
58   -import java.util.Set;
59   -
60   -/**
61   - * 用户密码与手机短信登录与注册服务:<br><br>
62   - * 1. 用于第三方登录与手机短信登录逻辑。<br><br>
63   - * 2. 用于用户密码登录逻辑。<br><br>
64   - * 3. 用户注册逻辑。<br><br>
65   - * @author YongWu zheng
66   - * @version V1.0 Created by 2020/9/20 11:06
67   - */
68   -@Service
69   -public class UserDetailsServiceImpl implements UmsUserDetailsService {
70   -
71   - private final Logger log = LoggerFactory.getLogger(this.getClass());
72   -
73   - @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
74   - @Autowired(required = false)
75   - private UserCache userCache;
76   -
77   - @Resource
78   - private SysUserService userService;
79   -
80   - /**
81   - * 用于密码加解密
82   - */
83   - @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
84   - @Autowired
85   - private PasswordEncoder passwordEncoder;
86   - @Autowired
87   - private SysPermissionService permissionService;
88   -
89   - @SuppressWarnings("AlibabaUndefineMagicConstant")
90   - @Override
91   - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
92   -
93   - try
94   - {
95   - // 从缓存中查询用户信息:
96   - // 从缓存中查询用户信息
97   - if (this.userCache != null)
98   - {
99   - UserDetails userDetails = this.userCache.getUserFromCache(username);
100   - if (userDetails != null)
101   - {
102   - return userDetails;
103   - }
104   - }
105   - // 根据用户名获取用户信息
106   - // 获取 username 对应的 SysUserDO
107   - SysUserDO user = userService.getUserByUsername(username);
108   - if (user == null) {
109   - throw new UsernameNotFoundException(username);
110   - }
111   - // 创建 LoginUser 对象
112   - Auth2LoginUser loginUser = SysAuthConvert.INSTANCE.getAuth2LoginUser(user);
113   - //TODO 登录日志等可以和用户名密码等兼容处理
114   - return loginUser;
115   - }
116   - catch (Exception e)
117   - {
118   - String msg = String.format("第三方登录 ======>: 登录用户名:%s, 登录失败: %s", username, e.getMessage());
119   - log.error(msg);
120   - throw new UserNotExistException(ErrorCodeEnum.QUERY_USER_INFO_ERROR, e, username);
121   - }
122   - }
123   -
124   - @Override
125   - public UserDetails registerUser(@NonNull AuthUser authUser, @NonNull String username,
126   - @NonNull String defaultAuthority, String decodeState) throws RegisterUserFailureException {
127   -
128   - // 这里的 decodeState 可以根据自己实现的 top.dcenter.ums.security.core.oauth.service.Auth2StateCoder 接口的逻辑来传递必要的参数.
129   - // 比如: 第三方登录成功后的跳转地址
130   - final RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
131   - // 假设 decodeState 就是 redirectUrl, 我们直接把 redirectUrl 设置到 request 上
132   - // 后续经过成功处理器时直接从 requestAttributes.getAttribute("redirectUrl", RequestAttributes.SCOPE_REQUEST) 获取并跳转
133   - if (requestAttributes != null) {
134   - requestAttributes.setAttribute("redirectUrl", decodeState, RequestAttributes.SCOPE_REQUEST);
135   - }
136   - //返回用户
137   - LoginUser loginUser = doRegistUser(authUser);
138   -
139   - log.info("第三方用户注册 ======>: 用户名:{}, 注册成功", username);
140   -
141   - // 把用户信息存入缓存
142   - if (userCache != null)
143   - {
144   - userCache.putUserInCache(loginUser);
145   - }
146   -
147   - return loginUser;
148   - }
149   -
150   - private LoginUser doRegistUser(AuthUser authUser) {
151   - SysUserCreateReqVO reqVO = SysAuthConvert.INSTANCE.convert(authUser);
152   - if (StringUtils.isEmpty(reqVO.getPassword())) {
153   - reqVO.setPassword(getDefaultPassword());
154   - }
155   - //添加用户
156   - Long sysUserId = userService.createUser(reqVO);
157   - //关联第三方用户
158   - Long userId = userService.bindSocialUSer(sysUserId, authUser.getUuid());
159   - //赋予默认角色权限;三方登录默认部分
160   - permissionService.assignUserRole(userId, getDefaultRoles());
161   - LoginUser loginUser = SysAuthConvert.INSTANCE.getLoginUser(authUser);
162   - loginUser.setRoleIds(getDefaultRoles());
163   - loginUser.setPassword(getDefaultPassword());
164   - loginUser.setId(sysUserId);
165   - return loginUser;
166   - }
167   -
168   - private String getDefaultPassword() {
169   - return "123456";
170   - }
171   -
172   - protected Set<Long> getDefaultRoles() {
173   - return Sets.newHashSet(1L);
174   - }
175   -
176   - @NonNull
177   - public UserDetails registerUser(@NonNull String mobile, Map<String, String> otherParamMap) throws RegisterUserFailureException {
178   -
179   - // 用户信息持久化逻辑。。。
180   - // ...
181   -
182   - log.info("Demo ======>: 手机短信登录用户 {}:注册成功", mobile);
183   -
184   - User user = new User(mobile,
185   - passwordEncoder.encode("admin"),
186   - true,
187   - true,
188   - true,
189   - true,
190   - AuthorityUtils.commaSeparatedStringToAuthorityList("admin, ROLE_USER")
191   - );
192   -
193   - // 把用户信息存入缓存
194   - if (userCache != null)
195   - {
196   - userCache.putUserInCache(user);
197   - }
198   -
199   - return user;
200   - }
201   -
202   - /**
203   - * {@link #existedByUsernames(String...)} usernames 生成规则.
204   - * 如需自定义重新实现此逻辑
205   - * @param authUser 第三方用户信息
206   - * @return 返回一个 username 数组
207   - */
208   - @Override
209   - public String[] generateUsernames(AuthUser authUser) {
210   - return new String[]{
211   - authUser.getUsername(),
212   - // providerId = authUser.getSource()
213   - authUser.getUsername() + "_" + authUser.getSource(),
214   - // providerUserId = authUser.getUuid()
215   - authUser.getUsername() + "_" + authUser.getSource() + "_" + authUser.getUuid()
216   - };
217   - }
218   -
219   - @Override
220   - public UserDetails loadUserByUserId(String userId) throws UsernameNotFoundException {
221   - UserDetails userDetails = loadUserByUsername(userId);
222   - User.withUserDetails(userDetails);
223   - return userDetails;
224   - }
225   -
226   - @Override
227   - public List<Boolean> existedByUsernames(String... usernames) throws UsernameNotFoundException {
228   - // ... 在本地账户上查询 userIds 是否已被使用
229   - List<Boolean> list = new ArrayList<>();
230   - for (String username : usernames) {
231   - SysUserDO userDO = userService.getUserByUsername(username);
232   - list.add(userDO != null);
233   - }
234   - return list;
235   - }
236   -
237   -}
238 0 \ No newline at end of file
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserServiceImpl.java
... ... @@ -4,7 +4,7 @@ import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.io.IoUtil;
5 5 import cn.hutool.core.util.IdUtil;
6 6 import cn.hutool.core.util.StrUtil;
7   -import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.social.SysUserSocialDO;
  7 +import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserSocialDO;
8 8 import cn.iocoder.yudao.adminserver.modules.system.dal.mysql.social.SysUserSocialMapper;
9 9 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
10 10 import cn.iocoder.yudao.framework.common.exception.ServiceException;
... ... @@ -82,7 +82,7 @@ public class SysUserServiceImpl implements SysUserService {
82 82 public Long bindSocialUSer(Long sysUserId, String socialUSerId) {
83 83 SysUserSocialDO userSocialDO = new SysUserSocialDO();
84 84 userSocialDO.setUserId(sysUserId);
85   - userSocialDO.setSocialUserId(socialUSerId);
  85 +// userSocialDO.setSocialUserId(socialUSerId);
86 86 userSocialMapper.insert(userSocialDO);
87 87 return userSocialDO.getUserId();
88 88 }
... ...
yudao-admin-server/src/main/resources/application-local.yaml
... ... @@ -168,220 +168,13 @@ yudao:
168 168 - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
169 169 demo: false # 关闭演示模式
170 170  
171   -
172   -# ums core
173   -ums:
174   - one-click-login:
175   - # 一键登录是否开启, 默认 false
176   - enable: true
177   - # 一键登录请求处理 url, 默认 /authentication/one-click
178   - login-processing-url: /authentication/one-click
179   - # token 参数名称, 默认: accessToken
180   - token-param-name: accessToken
181   - # 其他请求参数名称列表(包括请求头名称), 此参数会传递到 OneClickLoginService.callback(String, Map)
182   - # 与 UserDetailsRegisterService.registerUser(String, Map); 默认为: 空
183   - other-param-names:
184   - - imei
185   - # ================ 第三方授权登录相关配置 ================
186   - oauth:
187   - # 第三方授权登录后如未注册用户是否支持自动注册功能, 默认: true
188   - auto-sign-up: true
189   - # 第三方授权登录后如未注册用户不支持自动注册功能, 则跳转到此 url 进行注册逻辑, 此 url 必须开发者自己实现; 默认: /signUp.html;
190   - # 注意: 当 autoSignUp = false 时, 此属性才生效.
191   - # 例如: 1. 设置值 "/signUp", 则跳转指定到 "/signUp" 进行注册.
192   - # 2. 想返回自定义 json 数据到前端, 这里要设置 null , 在 Auth2LoginAuthenticationFilter 设置的 AuthenticationSuccessHandler
193   - # 上处理返回 json; 判断是否为临时用户的条件是: Authentication.getPrincipal() 是否为 TemporaryUser 类型.
194   - sign-up-url: null
195   - # 用于第三方授权登录时, 未开启自动注册且用户是第一次授权登录的临时用户密码, 默认为: "". 注意: 生产环境更换密码
196   - temporary-user-password: ""
197   - # 用于第三方授权登录时, 未开启自动注册且用户是第一次授权登录的临时用户的默认权限, 多个权限用逗号分开, 默认为: "ROLE_TEMPORARY_USER"
198   - temporary-user-authorities: ROLE_TEMPORARY_USER
199   - # 抑制反射警告, 支持 JDK11, 默认: false , 在确认 WARNING: An illegal reflective access operation has occurred 安全后, 可以打开此设置, 可以抑制反射警告.
200   - suppress-reflect-warning: true
201   - # 第三方服务商: providerId, 支持所有 JustAuth 支持的第三方授权登录, 目前有 32 家第三方授权登录
202   - github:
203   - # 根据是否有设置 clientId 来动态加载相应 JustAuth 的 AuthXxxRequest
204   - client-id: 4d4ee00e82f669f2ea8d
205   - client-secret: 4050be113a83556b63bd991d606fded437b05235
206   - scopes:
207   - # - 'repo:status'
208   - # - 'public_repo'
209   - # - 'repo:invite'
210   - # - 'user:follow'
211   - gitee:
212   - client-id: eb5e3298cc10ead57cd40f9f36e7154ab2ea54dcb519684d7e10ca3fec5b1c1a
213   - client-secret: 495b5542dc007e2d46d316c527bd05dac586f2ec31b96c551e164387b5edb1cb
214   - scopes:
215   - - user_info
216   -# # 自定义 OAuth2 Login
217   -# customize:
218   -# client-id: c971cf1634460e18310a5d7cb0f55d7d143a72015b2f29aee6a0e8911efac7eb
219   -# client-secret: 309c9521721e3eb385a99a6bde2755f3107c7e15f3b8e0527c9f3ea4d1ce33bb
220   -# # 自定义第三方授权登录时, 当 Auth2Properties#customize 时有效, 此字段必须以驼峰方式命名.
221   -# # 比如此字段的值为 umsCustomize, 那么 /auth2/authorization/customize 会替换为 /auth2/authorization/umsCustomize
222   -# customize-provider-id: giteeCustomize
223   -# # 自定义第三方授权登录, 当 Auth2Properties#customize 时有效, 设置第三方是否在国外, 默认: false.
224   -# # 如果为 false 时, 设置 {@link HttpConfig} 的超时时间为 ums.oauth.proxy.timeout 的值.
225   -# # 如果为 true 时, 设置 {@link HttpConfig} 的超时时间为 ums.oauth.proxy.foreignTimeout 的值.
226   -# customize-is-foreign: false
227   - # 第三方登录授权登录 url 前缀, 不包含 ServletContextPath,默认为 /auth2/authorization.
228   - auth-login-url-prefix: /api/auth2/authorization
229   - # 第三方登录回调处理 url 前缀 ,也就是 RedirectUrl 的前缀, 不包含 ServletContextPath,默认为 /auth2/login.
230   - redirect-url-prefix: /api/auth2/login
231   - # 第三方登录回调的域名, 例如:http://localhost:9090 默认为 "http://127.0.0.1",
232   - # redirectUrl 直接由 {domain}/{servletContextPath}/{redirectUrlPrefix}/{providerId}(ums.oauth.[qq/gitee/weibo])组成
233   - domain: http://localhost:48080
234   - # 第三方授权登录成功后的默认权限, 多个权限用逗号分开, 默认为: "ROLE_USER"
235   - default-authorities: ROLE_USER
236   - # 是否支持内置的第三方登录用户表(user_connection) 和 auth_token 表. 默认: true.
237   - # 注意: 如果为 false, 则必须重新实现 ConnectionService 接口.
238   - enable-user-connection-and-auth-token-table: true
239   - # 是否支持内置的第三方登录 token 表(auth_token). 默认: true.
240   - enable-auth-token-table: true
241   -
242   -
243   - # ================ start: 定时刷新 access token 定时任务相关配置 ================
244   -
245   - # 是否支持定时刷新 AccessToken 定时任务. 默认: false.
246   - # 支持分布式(分布式 IOC 容器中必须有 RedisConnectionFactory, 也就是说, 是否分布式执行依据 IOC 容器中是否有 RedisConnectionFactory)
247   - enableRefreshTokenJob: false
248   - # A cron-like expression. 0 * 2 * * ? 分别对应: second/minute/hour/day of month/month/day of week,
249   - # 默认为: "0 * 2 * * ?", 凌晨 2 点启动定时任务, 支持分布式(分布式 IOC 容器中必须有 {@link RedisConnectionFactory},
250   - # 也就是说, 是否分布式执行依据 IOC 容器中是否有 {@link RedisConnectionFactory})
251   - refresh-token-job-cron: 0 0/5 * * * ?
252   - # 定时刷新 accessToken 任务时, 批处理数据库的记录数. 注意: 分布式应用时, 此配置不同服务器配置必须是一样的. batchCount 大小需要根据实际生产环境进行优化
253   - batch-count: 1000
254   - # accessToken 的剩余有效期内进行刷新 accessToken, 默认: 24, 单位: 小时. 注意: 需要根据实际生产环境进行优化
255   - remaining-expire-in: 24
256   -
257   - # ================ start: 定时刷新 access token 定时任务相关配置 ================
258   -
259   - # JustAuth 内部参数设置
260   - just-auth:
261   - # 忽略校验 state 参数,默认不开启。当 ignoreCheckState 为 true 时, me.zhyd.oauth.request.AuthDefaultRequest.login(AuthCallback) 将不会校验 state 的合法性。
262   - # 使用场景:当且仅当使用自实现 state 校验逻辑时开启
263   - # 以下场景使用方案仅作参考:
264   - # 1. 授权、登录为同端,并且全部使用 JustAuth 实现时,该值建议设为 false;
265   - # 2. 授权和登录为不同端实现时,比如前端页面拼装 authorizeUrl,并且前端自行对state进行校验,后端只负责使用code获取用户信息时,该值建议设为 true;
266   - # 如非特殊需要,不建议开启这个配置
267   - # 该方案主要为了解决以下类似场景的问题:Since: 1.15.6, See Also: https://github.com/justauth/JustAuth/issues/83
268   - ignoreCheckState: false
269   - # 默认 state 缓存过期时间:3分钟(PT180S) 鉴于授权过程中,根据个人的操作习惯,或者授权平台的不同(google等),每个授权流程的耗时也有差异,
270   - # 不过单个授权流程一般不会太长 本缓存工具默认的过期时间设置为3分钟,即程序默认认为3分钟内的授权有效,超过3分钟则默认失效,失效后删除
271   - # 注意: 这是为了测试打断点时用的, 生产环境自己设置为合适数组或默认
272   - timeout: PT1800S
273   - # JustAuth state 缓存类型, 默认 session
274   - cacheType: session
275   - # JustAuth state 缓存 key 前缀
276   - cacheKeyPrefix: 'JUST_AUTH:'
277   -
278   - # 用于 JustAuth 的代理(HttpClient)设置
279   - proxy:
280   - # 是否支持代理, 默认为: false.
281   - enable: false
282   - # 针对国外服务可以单独设置代理类型, 默认 Proxy.Type.HTTP, enable = true 时生效.
283   - proxy: HTTP
284   - # 代理 host, enable = true 时生效.
285   - hostname:
286   - # 代理端口, enable = true 时生效.
287   - port:
288   - # 用于国内代理(HttpClient)超时, 默认 PT3S
289   - timeout: PT3S
290   - # 用于国外网站代理(HttpClient)超时, 默认 PT15S
291   - foreign-timeout: PT150S
292   -
293   -
294   - # =============== start: 第三方登录时用的数据库表 user_connection 与 auth_token 添加 redis cache ===============
  171 +justauth:
  172 + enabled: true
  173 + type:
  174 + GITEE:
  175 + client-id: 6bb0b37a8a017e5e2dc4c34ca4756dcf80e8e392585e7035d3ede7a6db50426e
  176 + client-secret: f117b9de5e9267bcd48db83d4cb078ea8cf9a5d17cda83481e3d9090df3fa01d
  177 + ignore-check-redirect-uri: true
  178 +# redirect-uri: http://127.0.0.1:48080/api/gitee/callback
295 179 cache:
296   - # redisCacheManager 设置, 默认实现: 对查询结果 null 值进行缓存, 添加时更新缓存 null 值.
297   - redis:
298   - # 是否开启缓存, 默认 false
299   - open: false
300   - # 是否使用 spring IOC 容器中的 RedisConnectionFactory, 默认: false
301   - # 如果使用 spring IOC 容器中的 RedisConnectionFactory,则要注意 cache.database-index 要与 spring.redis.database 一样。
302   - use-ioc-redis-connection-factory: true
303   - cache:
304   - # redis cache 存放的 database index, 默认: 0
305   - database-index: 1
306   - # 设置缓存管理器管理的缓存的默认过期时间, 默认: 200s
307   - default-expire-time: PT200S
308   - # cache ttl 。使用 0 声明一个永久的缓存。 默认: 180, 单位: 秒<br>
309   - # 取缓存时间的 20% 作为动态的随机变量上下浮动, 防止同时缓存失效而缓存击穿
310   - entry-ttl: PT180S
311   - # Names of the default caches to consider for caching operations defined in the annotated class.
312   - # 此设置不对 user_connection 与 auth_token 使用的缓存名称(UCC/UCHC/UCHACC)产生影响.
313   - cache-names:
314   - - cacheName
315   - # =============== end: 第三方登录时用的数据库表 user_connection 与 auth_token 添加 redis cache ===============
316   -
317   - # =============== start: 线程池配置 ===============
318   - executor:
319   - # 启动第三方授权登录用户的 accessToken 的定时任务时的 Executor 属性, 注意: 需要根据实际生产环境进行优化
320   - job-task-scheduled-executor:
321   - # 线程池中空闲时保留的线程数, 默认: 0
322   - core-pool-size: 0
323   - # keep alive time, 默认: 10
324   - keep-alive-time: 0
325   - # keepAliveTime 时间单位, 默认: 毫秒
326   - time-unit: milliseconds
327   - # 线程池名称, 默认: accessTokenJob
328   - pool-name: accessTokenJob
329   - # 拒绝策略, 默认: ABORT
330   - rejected-execution-handler-policy: abort
331   - # 线程池关闭过程的超时时间, 默认: PT10S
332   - executor-shutdown-timeout: PT10S
333   - # 更新第三方授权登录用户的 accessToken 的执行逻辑, 向本地数据库 auth_token 表获取过期或在一定时间内过期的 token 记录,
334   - # 用 refreshToken 向第三方服务商更新 accessToken 信息的 Executor 属性,
335   - # 注意: 定时刷新 accessToken 的执行逻辑是多线程的, 需要根据实际生产环境进行优化
336   - refresh-token:
337   - # 程池中空闲时保留的线程数, 默认: 0
338   - core-pool-size: 0
339   - # 最大线程数, 默认: 本机核心数
340   - maximum-pool-size: 8
341   - # keep alive time, 默认: 5
342   - keep-alive-time: 5
343   - # keepAliveTime 时间单位, 默认: 秒
344   - time-unit: seconds
345   - # blocking queue capacity, 默认: maximumPoolSize * 2
346   - blocking-queue-capacity: 16
347   - # 线程池名称, 默认: refreshToken
348   - pool-name: refreshToken
349   - # 拒绝策略, 默认: CALLER_RUNS 注意: 一般情况下不要更改默认设置, 没有实现 RefreshToken 逻辑被拒绝执行后的处理逻辑, 除非自己实现RefreshTokenJob.refreshTokenJob() 对 RefreshToken 逻辑被拒绝执行后的处理逻辑.
350   - rejected-execution-handler-policy: caller_runs
351   - # 线程池关闭过程的超时时间, 默认: 10 秒
352   - executor-shutdown-timeout: PT10S
353   - # 第三方授权登录时, 异步更新用户的第三方授权用户信息与 token 信息的 Executor 属性,
354   - # 注意: 第三方授权登录时是异步更新第三方用户信息与 token 信息到本地数据库时使用此配置, 需要根据实际生产环境进行优化
355   - user-connection-update:
356   - # 程池中空闲时保留的线程数, 默认: 5
357   - core-pool-size: 5
358   - # 最大线程数, 默认: 本机核心数
359   - maximum-pool-size: 8
360   - # keep alive time, 默认: 10
361   - keep-alive-time:
362   - # keepAliveTime 时间单位, 默认: 秒
363   - time-unit: seconds
364   - # blocking queue capacity, 默认: maximumPoolSize * 2
365   - blocking-queue-capacity: 16
366   - # 线程池名称, 默认: updateConnection
367   - pool-name: updateConnection
368   - # 拒绝策略, 默认: CALLER_RUNS 注意: 一般情况下不要更改默认设置, 除非自己实现Auth2LoginAuthenticationProvider更新逻辑;
369   - # 改成 ABORT 也支持, 默认实现 Auth2LoginAuthenticationProvider 是异步更新被拒绝执行后, 会执行同步更新.
370   - rejected-execution-handler-policy: caller_runs
371   - # 线程池关闭过程的超时时间, 默认: PT10S
372   - executor-shutdown-timeout: PT10S
373   - # =============== end: 线程池配置 ===============
374   -
375   - # =============== start: user_connection repository 配置 ===============
376   - repository:
377   -
378   - # 第三方登录用户数据库表的字段 accessToken 与 refreshToken 加密专用密码
379   - text-encryptor-password: 7ca5d913a17b4942942d16a974e3fecc
380   - # 第三方登录用户数据库表的字段 accessToken 与 refreshToken 加密专用 salt
381   - text-encryptor-salt: cd538b1b077542aca5f86942b6507fe2
382   - # 是否在启动时检查并自动创建 userConnectionTableName 与 authTokenTableName, 默认: TRUE
383   - enableStartUpInitializeTable: true
384   - # 其他的有: 数据库表名称, 字段名称, curd sql 语句 等设置, 一般不需要更改,
385   - # 如果要添加字段: 具体查看 RepositoryProperties 与 Auth2JdbcUsersConnectionRepository
386   - # =============== end: user_connection repository 配置 ===============
387   -
  180 + type: default
... ...
yudao-admin-ui/src/api/login.js
... ... @@ -40,9 +40,9 @@ export function getCodeImg() {
40 40 }
41 41  
42 42 // 接入第三方登录
43   -export function oAuthLogin(provider) {
  43 +export function oAuthLogin(type, redirectUri) {
44 44 return request({
45   - url: '/auth2/authorization/' + provider,
  45 + url: '/third-login-redirect?type=' + type + '&redirectUri=' + redirectUri,
46 46 method: 'get'
47 47 })
48 48 }
... ...
yudao-admin-ui/src/views/login.vue
... ... @@ -8,24 +8,12 @@
8 8 </el-input>
9 9 </el-form-item>
10 10 <el-form-item prop="password">
11   - <el-input
12   - v-model="loginForm.password"
13   - type="password"
14   - auto-complete="off"
15   - placeholder="密码"
16   - @keyup.enter.native="handleLogin"
17   - >
  11 + <el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码" @keyup.enter.native="handleLogin">
18 12 <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
19 13 </el-input>
20 14 </el-form-item>
21 15 <el-form-item prop="code">
22   - <el-input
23   - v-model="loginForm.code"
24   - auto-complete="off"
25   - placeholder="验证码"
26   - style="width: 63%"
27   - @keyup.enter.native="handleLogin"
28   - >
  16 + <el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%" @keyup.enter.native="handleLogin">
29 17 <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
30 18 </el-input>
31 19 <div class="login-code">
... ... @@ -34,18 +22,12 @@
34 22 </el-form-item>
35 23 <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
36 24 <el-form-item style="width:100%;">
37   - <el-button
38   - :loading="loading"
39   - size="medium"
40   - type="primary"
41   - style="width:100%;"
42   - @click.native.prevent="handleLogin"
43   - >
  25 + <el-button :loading="loading" size="medium" type="primary" style="width:100%;" @click.native.prevent="handleLogin">
44 26 <span v-if="!loading">登 录</span>
45 27 <span v-else>登 录 中...</span>
46 28 </el-button>
47 29 </el-form-item>
48   -
  30 +
49 31 <el-form-item style="width:100%;">
50 32 <div class="oauth-login" style="display:flex">
51 33 <div class="oauth-login-item" v-for="item in oauthProviders" :key="item.code" @click="doAuth2Login(item)">
... ... @@ -80,21 +62,19 @@ export default {
80 62 code: "",
81 63 uuid: ""
82 64 },
83   - oauthProviders: [
84   - {
  65 + oauthProviders: [{
85 66 img: "https://cdn.jsdelivr.net/gh/justauth/justauth-oauth-logo@1.2/gitee.png",
86 67 title: "码云",
87   - code: "gitee"
88   - },
89   - {
  68 + source: "gitee",
  69 + type: 10
  70 + }, {
90 71 img: "https://cdn.jsdelivr.net/gh/justauth/justauth-oauth-logo@1.2/wechat.png",
91 72 title: "微信",
92   - code: "weixin"
93   - },
94   - {
  73 + source: "weixin"
  74 + }, {
95 75 img: "https://cdn.jsdelivr.net/gh/justauth/justauth-oauth-logo@1.2/qq.png",
96 76 title: "QQ",
97   - code: "qq"
  77 + source: "qq"
98 78 }
99 79 ],
100 80 loginRules: {
... ... @@ -163,11 +143,15 @@ export default {
163 143 });
164 144 },
165 145 doAuth2Login(provider) {
166   - console.log("开始Oauth登录...%o", provider.code);
  146 + // console.log("开始Oauth登录...%o", provider.code);
  147 + // 设置登陆中
167 148 this.loading = true;
168   - oAuthLogin(provider.code).then((res) => {
169   - console.log(res.url);
170   - window.location.href = res.url;
  149 + // 计算 redirectUri
  150 + const redirectUri = location.origin + '/third-login';
  151 + // 进行跳转
  152 + oAuthLogin(provider.type, redirectUri).then((res) => {
  153 + // console.log(res.url);
  154 + window.location.href = res.data;
171 155 });
172 156 }
173 157 }
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/http/HttpUtils.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.common.util.http;
  2 +
  3 +import cn.hutool.core.io.FileUtil;
  4 +import cn.hutool.core.map.TableMap;
  5 +import cn.hutool.core.net.url.UrlBuilder;
  6 +import cn.hutool.core.util.ReferenceUtil;
  7 +import cn.hutool.core.util.ReflectUtil;
  8 +
  9 +import java.nio.charset.Charset;
  10 +
  11 +/**
  12 + * HTTP 工具类
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +public class HttpUtils {
  17 +
  18 + @SuppressWarnings("unchecked")
  19 + public static String replaceUrlQuery(String url, String key, String value) {
  20 + UrlBuilder builder = UrlBuilder.of(url, Charset.defaultCharset());
  21 + // 先移除
  22 + TableMap<CharSequence, CharSequence> query = (TableMap<CharSequence, CharSequence>)
  23 + ReflectUtil.getFieldValue(builder.getQuery(), "query");
  24 + query.remove(key);
  25 + // 后添加
  26 + builder.addQuery(key, value);
  27 + return builder.build();
  28 + }
  29 +
  30 +}
... ...
yudao-framework/yudao-spring-boot-starter-security/pom.xml
... ... @@ -44,19 +44,6 @@
44 44 <artifactId>spring-boot-starter-security</artifactId>
45 45 </dependency>
46 46  
47   - <!-- justAuth 集成第三方登录 -->
48   - <dependency>
49   - <groupId>top.dcenter</groupId>
50   - <artifactId>justAuth-spring-security-starter</artifactId>
51   - <version>1.1.25</version>
52   - <exclusions>
53   - <exclusion>
54   - <artifactId>slf4j-api</artifactId>
55   - <groupId>org.slf4j</groupId>
56   - </exclusion>
57   - </exclusions>
58   - </dependency>
59   -
60 47 </dependencies>
61 48  
62 49 </project>
... ...
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoWebSecurityConfigurerAdapter.java
... ... @@ -24,9 +24,6 @@ import org.springframework.security.web.access.AccessDeniedHandler;
24 24 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
25 25 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
26 26 import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
27   -import top.dcenter.ums.security.core.oauth.config.Auth2AutoConfigurer;
28   -import top.dcenter.ums.security.core.oauth.properties.Auth2Properties;
29   -import top.dcenter.ums.security.core.oauth.properties.OneClickLoginProperties;
30 27  
31 28 import javax.annotation.Resource;
32 29  
... ... @@ -80,15 +77,6 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap
80 77 @Resource
81 78 private Customizer<ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry> authorizeRequestsCustomizer;
82 79  
83   - @Autowired
84   - private Auth2AutoConfigurer auth2AutoConfigurer;
85   - @Autowired
86   - private Auth2Properties auth2Properties;
87   - @Autowired
88   - private OneClickLoginProperties oneClickLoginProperties;
89   - @Autowired
90   - private AbstractSignUpUrlAuthenticationSuccessHandler authenticationSuccessHandler;
91   -
92 80 /**
93 81 * 由于 Spring Security 创建 AuthenticationManager 对象时,没声明 @Bean 注解,导致无法被注入
94 82 * 通过覆写父类的该方法,添加 @Bean 注解,解决该问题
... ... @@ -129,9 +117,6 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap
129 117 @Override
130 118 protected void configure(HttpSecurity httpSecurity) throws Exception {
131 119 httpSecurity
132   - // ========= start: 使用 justAuth-spring-security-starter 必须步骤 =========
133   - // 添加 Auth2AutoConfigurer 使 OAuth2(justAuth) login 生效.
134   - .apply(this.auth2AutoConfigurer).and()
135 120 // 开启跨域
136 121 .cors().and()
137 122 // CSRF 禁用,因为不使用 Session
... ... @@ -174,19 +159,6 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap
174 159 // 添加 JWT Filter
175 160 httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
176 161  
177   -// // 放行第三方登录入口地址与第三方登录回调地址
178   -// // @formatter:off
179   -// httpSecurity.authorizeRequests()
180   -// .antMatchers(HttpMethod.GET,
181   -// auth2Properties.getRedirectUrlPrefix() + "/*",
182   -// auth2Properties.getAuthLoginUrlPrefix() + "/*")
183   -// .permitAll();
184   -// httpSecurity.authorizeRequests()
185   -// .antMatchers(HttpMethod.POST,
186   -// oneClickLoginProperties.getLoginProcessingUrl())
187   -// .permitAll();
188   -// // @formatter:on
189   -// // ========= end: 使用 justAuth-spring-security-starter 必须步骤 =========
190 162 }
191 163  
192 164 private String api(String url) {
... ...
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/Auth2LoginUser.java deleted
1   -package cn.iocoder.yudao.framework.security.core;
2   -
3   -import com.alibaba.fastjson.JSONObject;
4   -import lombok.AllArgsConstructor;
5   -import lombok.Data;
6   -import me.zhyd.oauth.enums.AuthUserGender;
7   -import me.zhyd.oauth.model.AuthToken;
8   -
9   -/**
10   - * @author weir
11   - */
12   -@Data
13   -public class Auth2LoginUser extends LoginUser {
14   - /**
15   - * 是否为临时注册的临时用户
16   - */
17   - private boolean isTempUser;
18   - /**
19   - * 用户第三方系统的唯一id。在调用方集成该组件时,可以用uuid + source唯一确定一个用户
20   - */
21   - private String thirdPartyUserId;
22   - /**
23   - * 用户昵称
24   - */
25   - private String nickname;
26   - /**
27   - * 用户头像
28   - */
29   - private String avatar;
30   - /**
31   - * 用户网址
32   - */
33   - private String blog;
34   - /**
35   - * 所在公司
36   - */
37   - private String company;
38   - /**
39   - * 位置
40   - */
41   - private String location;
42   - /**
43   - * 用户邮箱
44   - */
45   - private String email;
46   - /**
47   - * 用户备注(各平台中的用户个人介绍)
48   - */
49   - private String remark;
50   - /**
51   - * 性别
52   - */
53   - private AuthUserGender gender;
54   - /**
55   - * 用户来源
56   - */
57   - private String source;
58   - /**
59   - * 用户授权的token信息
60   - */
61   - private AuthToken token;
62   - /**
63   - * 第三方平台返回的原始用户信息
64   - */
65   - private JSONObject rawUserInfo;
66   -}
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/handler/AbstractSignUpUrlAuthenticationSuccessHandler.java
... ... @@ -22,24 +22,16 @@
22 22 */
23 23 package cn.iocoder.yudao.framework.security.core.handler;
24 24  
25   -import cn.iocoder.yudao.framework.security.core.LoginUser;
26   -import org.springframework.http.HttpStatus;
27 25 import org.springframework.security.core.Authentication;
28 26 import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
29 27 import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
30 28 import org.springframework.security.web.savedrequest.RequestCache;
31   -import org.springframework.security.web.savedrequest.SavedRequest;
32   -import top.dcenter.ums.security.core.oauth.userdetails.TemporaryUser;
33   -import top.dcenter.ums.security.core.vo.ResponseResult;
34 29  
35 30 import javax.servlet.ServletException;
36 31 import javax.servlet.http.HttpServletRequest;
37 32 import javax.servlet.http.HttpServletResponse;
38 33 import java.io.IOException;
39 34  
40   -import static org.springframework.util.StringUtils.hasText;
41   -import static top.dcenter.ums.security.core.oauth.util.MvcUtil.*;
42   -
43 35 /**
44 36 * @author weir
45 37 */
... ...