mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 18:28:43 +08:00 
			
		
		
		
	接入 dingtalk 钉钉的三方登陆,流程未接入
This commit is contained in:
		| @@ -1,29 +1,22 @@ | ||||
| package cn.iocoder.yudao.adminserver.modules.system.controller.auth; | ||||
|  | ||||
| import cn.hutool.core.net.url.UrlBuilder; | ||||
| import cn.hutool.http.HttpUtil; | ||||
| import cn.hutool.json.JSONUtil; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.enums.user.SysUserSocialTypeEnum; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.service.auth.SysUserSessionService; | ||||
| import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||||
| import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||||
| import cn.iocoder.yudao.framework.common.util.http.HttpUtils; | ||||
| import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthLoginReqVO; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthLoginRespVO; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthMenuRespVO; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthPermissionInfoRespVO; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.*; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.convert.auth.SysAuthConvert; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.permission.SysMenuDO; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.permission.SysRoleDO; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.enums.permission.MenuTypeEnum; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.enums.user.SysUserSocialTypeEnum; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.service.auth.SysAuthService; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysRoleService; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; | ||||
| import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||||
| import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||||
| import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | ||||
| import com.aliyuncs.CommonResponse; | ||||
| import cn.iocoder.yudao.framework.common.util.http.HttpUtils; | ||||
| import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | ||||
| import com.xkcoding.justauth.AuthRequestFactory; | ||||
| import io.swagger.annotations.Api; | ||||
| import io.swagger.annotations.ApiImplicitParam; | ||||
| @@ -35,26 +28,18 @@ 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.apache.commons.lang.StringUtils; | ||||
| import org.quartz.SimpleTrigger; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.web.multipart.MultipartFile; | ||||
| import org.springframework.web.util.UriBuilder; | ||||
|  | ||||
| import javax.annotation.Resource; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| import javax.validation.Valid; | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| import java.nio.charset.Charset; | ||||
| import java.util.List; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||||
| import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | ||||
| import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserRoleIds; | ||||
| import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; | ||||
| import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getUserAgent; | ||||
| import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | ||||
| import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserRoleIds; | ||||
|  | ||||
| @Api(tags = "认证") | ||||
| @RestController | ||||
| @@ -71,8 +56,6 @@ public class SysAuthController { | ||||
|     private SysRoleService roleService; | ||||
|     @Resource | ||||
|     private SysPermissionService permissionService; | ||||
|     @Resource | ||||
|     private SysUserSessionService sysUserSessionService; | ||||
|  | ||||
|     @Resource | ||||
|     private AuthRequestFactory authRequestFactory; | ||||
| @@ -86,42 +69,6 @@ public class SysAuthController { | ||||
|         return success(SysAuthLoginRespVO.builder().token(token).build()); | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/third-login-redirect") | ||||
|     @ApiOperation("三方登陆的跳转") | ||||
|     @ApiImplicitParams({ | ||||
|             @ApiImplicitParam(name = "type", value = "三方类型", required = true, dataTypeClass = Integer.class), | ||||
|             @ApiImplicitParam(name = "redirectUri", value = "回调路径", dataTypeClass = String.class) | ||||
|     }) | ||||
|     public CommonResult<String> login(@RequestParam("type") Integer type, | ||||
|                                       @RequestParam("redirectUri") String redirectUri) throws IOException { | ||||
|         // 获得对应的 AuthRequest 实现 | ||||
|         AuthRequest authRequest = authRequestFactory.get(SysUserSocialTypeEnum.valueOfType(type).getSource()); | ||||
|         // 生成跳转地址 | ||||
|         String authorizeUri = authRequest.authorize(AuthStateUtils.createState()); | ||||
|         authorizeUri = HttpUtils.replaceUrlQuery(authorizeUri, "redirect_uri", redirectUri); | ||||
| //        authorizeUri = UrlBuilder.fromBaseUrl(authorizeUri).queryParam("redirect_uri", redirectUri).build(); | ||||
|         return CommonResult.success(authorizeUri); | ||||
|     } | ||||
|  | ||||
|     @RequestMapping("/{type}/callback") | ||||
|     public AuthResponse login(@PathVariable String type, AuthCallback callback) { | ||||
|         AuthRequest authRequest = authRequestFactory.get(type); | ||||
|         AuthResponse<AuthUser> response = authRequest.login(callback); | ||||
|         log.info("【response】= {}", JSONUtil.toJsonStr(response)); | ||||
|         return response; | ||||
|     } | ||||
|  | ||||
| //    @RequestMapping("/auth2/login/{oauthType}") | ||||
| //    @ApiOperation("第三方登录") | ||||
| //    @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 | ||||
| //    public CommonResult<SysAuthLoginRespVO> login(@PathVariable String oauthType) { | ||||
| //        Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); | ||||
| //        //TODO NPE | ||||
| //        String token = sysUserSessionService.getSessionId(authentication.getName()); | ||||
| //        // 返回结果 | ||||
| //        return success(SysAuthLoginRespVO.builder().token(token).build()); | ||||
| //    } | ||||
|  | ||||
|     @GetMapping("/get-permission-info") | ||||
|     @ApiOperation("获取登陆用户的权限信息") | ||||
|     public CommonResult<SysAuthPermissionInfoRespVO> getPermissionInfo() { | ||||
| @@ -153,4 +100,38 @@ public class SysAuthController { | ||||
|         return success(SysAuthConvert.INSTANCE.buildMenuTree(menuList)); | ||||
|     } | ||||
|  | ||||
|     // ========== 三方登陆相关 ========== | ||||
|  | ||||
|     @GetMapping("/third-login-redirect") | ||||
|     @ApiOperation("三方登陆的跳转") | ||||
|     @ApiImplicitParams({ | ||||
|             @ApiImplicitParam(name = "type", value = "三方类型", required = true, dataTypeClass = Integer.class), | ||||
|             @ApiImplicitParam(name = "redirectUri", value = "回调路径", dataTypeClass = String.class) | ||||
|     }) | ||||
|     public CommonResult<String> thirdLoginRedirect(@RequestParam("type") Integer type, | ||||
|                                                    @RequestParam("redirectUri") String redirectUri) { | ||||
|         // 获得对应的 AuthRequest 实现 | ||||
|         AuthRequest authRequest = authRequestFactory.get(SysUserSocialTypeEnum.valueOfType(type).getSource()); | ||||
|         // 生成跳转地址 | ||||
|         String authorizeUri = authRequest.authorize(AuthStateUtils.createState()); | ||||
|         authorizeUri = HttpUtils.replaceUrlQuery(authorizeUri, "redirect_uri", redirectUri); | ||||
|         return CommonResult.success(authorizeUri); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/third-login") | ||||
|     @ApiOperation("三方登陆,使用 code 授权码") | ||||
|     @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 | ||||
|     public CommonResult<SysAuthLoginRespVO> thirdLogin(@RequestBody @Valid SysAuthThirdLoginReqVO reqVO) { | ||||
|         String token = authService.thirdLogin(reqVO, getClientIP(), getUserAgent()); | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     @RequestMapping("/{type}/callback") | ||||
|     public AuthResponse login(@PathVariable String type, AuthCallback callback) { | ||||
|         AuthRequest authRequest = authRequestFactory.get(type); | ||||
|         AuthResponse<AuthUser> response = authRequest.login(callback); | ||||
|         log.info("【response】= {}", JSONUtil.toJsonStr(response)); | ||||
|         return response; | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,37 @@ | ||||
| package cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth; | ||||
|  | ||||
| import cn.iocoder.yudao.adminserver.modules.system.enums.user.SysUserSocialTypeEnum; | ||||
| import cn.iocoder.yudao.framework.common.validation.InEnum; | ||||
| import io.swagger.annotations.ApiModel; | ||||
| import io.swagger.annotations.ApiModelProperty; | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.Builder; | ||||
| import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
| import org.hibernate.validator.constraints.Length; | ||||
|  | ||||
| import javax.validation.constraints.NotEmpty; | ||||
| import javax.validation.constraints.NotNull; | ||||
| import javax.validation.constraints.Pattern; | ||||
|  | ||||
| @ApiModel("三方登陆 Request VO,使用 code 授权码") | ||||
| @Data | ||||
| @NoArgsConstructor | ||||
| @AllArgsConstructor | ||||
| @Builder | ||||
| public class SysAuthThirdLoginReqVO { | ||||
|  | ||||
|     @ApiModelProperty(value = "三方平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") | ||||
|     @InEnum(SysUserSocialTypeEnum.class) | ||||
|     @NotNull(message = "三方平台的类型不能为空") | ||||
|     private Integer type; | ||||
|  | ||||
|     @ApiModelProperty(value = "授权码", required = true, example = "1024") | ||||
|     @NotEmpty(message = "授权码不能为空") | ||||
|     private String code; | ||||
|  | ||||
|     @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") | ||||
|     @NotEmpty(message = "state 不能为空") | ||||
|     private String state; | ||||
|  | ||||
| } | ||||
| @@ -2,6 +2,7 @@ package cn.iocoder.yudao.adminserver.modules.system.convert.auth; | ||||
|  | ||||
| import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthMenuRespVO; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthPermissionInfoRespVO; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthThirdLoginReqVO; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user.SysUserCreateReqVO; | ||||
| @@ -11,6 +12,7 @@ import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO | ||||
| import cn.iocoder.yudao.adminserver.modules.system.enums.permission.MenuIdEnum; | ||||
| import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||||
| import cn.iocoder.yudao.framework.security.core.LoginUser; | ||||
| import me.zhyd.oauth.model.AuthCallback; | ||||
| import me.zhyd.oauth.model.AuthUser; | ||||
| import org.mapstruct.Mapper; | ||||
| import org.mapstruct.Mapping; | ||||
| @@ -43,6 +45,8 @@ public interface SysAuthConvert { | ||||
|  | ||||
|     LoginUser convert(SysUserProfileUpdatePasswordReqVO reqVO); | ||||
|  | ||||
|     AuthCallback convert(SysAuthThirdLoginReqVO bean); | ||||
|  | ||||
|     /** | ||||
|      * 将菜单列表,构建成菜单树 | ||||
|      * | ||||
|   | ||||
| @@ -41,6 +41,7 @@ public class SysUserSocialDO extends BaseDO { | ||||
|      * 三方平台的类型 | ||||
|      */ | ||||
|     private SysUserSocialTypeEnum type; | ||||
|  | ||||
|     /** | ||||
|      * 三方 openid | ||||
|      */ | ||||
| @@ -56,6 +57,10 @@ public class SysUserSocialDO extends BaseDO { | ||||
|      * 如果没有 unionId 的平台,直接使用 openid 作为该字段的值 | ||||
|      */ | ||||
|     private String unionId; | ||||
|     /** | ||||
|      * 原始 Token 数据,一般是 JSON 格式 | ||||
|      */ | ||||
|     private String rawTokenInfo; | ||||
|  | ||||
|     /** | ||||
|      * 用户昵称 | ||||
| @@ -66,9 +71,9 @@ public class SysUserSocialDO extends BaseDO { | ||||
|      */ | ||||
|     private String avatar; | ||||
|     /** | ||||
|      * 原始数据,一般是 JSON 格式 | ||||
|      * 原始用户数据,一般是 JSON 格式 | ||||
|      */ | ||||
|     private String info; | ||||
|     private String rawUserInfo; | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.adminserver.modules.system.enums.user; | ||||
| import cn.hutool.core.util.ArrayUtil; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.enums.errorcode.SysErrorCodeTypeEnum; | ||||
| import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | ||||
| import com.fasterxml.jackson.annotation.JsonCreator; | ||||
| import jodd.util.ArraysUtil; | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.Getter; | ||||
| @@ -19,6 +20,7 @@ import java.util.Arrays; | ||||
| public enum SysUserSocialTypeEnum implements IntArrayValuable { | ||||
|  | ||||
|     GITEE(10, "GITEE"), // https://gitee.com/api/v5/oauth_doc#/ | ||||
|     DINGTALK(20, "DINGTALK"), // https://developers.dingtalk.com/document/app/obtain-identity-credentials | ||||
|     ; | ||||
|  | ||||
|     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SysUserSocialTypeEnum::getType).toArray(); | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| package cn.iocoder.yudao.adminserver.modules.system.service.auth; | ||||
|  | ||||
| import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthThirdLoginReqVO; | ||||
| import cn.iocoder.yudao.framework.security.core.service.SecurityAuthFrameworkService; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthLoginReqVO; | ||||
|  | ||||
| @@ -22,4 +23,14 @@ public interface SysAuthService extends SecurityAuthFrameworkService { | ||||
|      */ | ||||
|     String login(SysAuthLoginReqVO reqVO, String userIp, String userAgent); | ||||
|  | ||||
|     /** | ||||
|      * 三方登陆用户,使用 code 授权码 | ||||
|      * | ||||
|      * @param reqVO 登陆信息 | ||||
|      * @param userIp 用户 IP | ||||
|      * @param userAgent 用户 UA | ||||
|      * @return 身份令牌,使用 JWT 方式 | ||||
|      */ | ||||
|     String thirdLogin(SysAuthThirdLoginReqVO reqVO, String userIp, String userAgent); | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,11 @@ | ||||
| package cn.iocoder.yudao.adminserver.modules.system.service.auth.impl; | ||||
|  | ||||
| import cn.hutool.json.JSONUtil; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthThirdLoginReqVO; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.enums.user.SysUserSocialTypeEnum; | ||||
| import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||||
| import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; | ||||
| import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | ||||
| import cn.iocoder.yudao.framework.security.core.LoginUser; | ||||
| import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthLoginReqVO; | ||||
| @@ -17,7 +21,12 @@ import cn.iocoder.yudao.adminserver.modules.system.service.logger.SysLoginLogSer | ||||
| import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService; | ||||
| import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; | ||||
| import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; | ||||
| import com.xkcoding.justauth.AuthRequestFactory; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import me.zhyd.oauth.model.AuthCallback; | ||||
| import me.zhyd.oauth.model.AuthResponse; | ||||
| import me.zhyd.oauth.model.AuthUser; | ||||
| import me.zhyd.oauth.request.AuthRequest; | ||||
| import org.springframework.context.annotation.Lazy; | ||||
| import org.springframework.security.authentication.AuthenticationManager; | ||||
| import org.springframework.security.authentication.BadCredentialsException; | ||||
| @@ -60,6 +69,9 @@ public class SysAuthServiceImpl implements SysAuthService { | ||||
|     @Resource | ||||
|     private SysUserSessionService userSessionService; | ||||
|  | ||||
|     @Resource | ||||
|     private AuthRequestFactory authRequestFactory; | ||||
|  | ||||
|     @Override | ||||
|     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { | ||||
|         // 获取 username 对应的 SysUserDO | ||||
| @@ -97,6 +109,24 @@ public class SysAuthServiceImpl implements SysAuthService { | ||||
|         return userSessionService.createUserSession(loginUser, userIp, userAgent); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String thirdLogin(SysAuthThirdLoginReqVO reqVO, String userIp, String userAgent) { | ||||
|         // 使用 code 授权码,进行登陆 | ||||
|         AuthRequest authRequest = authRequestFactory.get(SysUserSocialTypeEnum.valueOfType(reqVO.getType()).getSource()); | ||||
|         AuthCallback authCallback = SysAuthConvert.INSTANCE.convert(reqVO); | ||||
|         AuthResponse<?> authResponse = authRequest.login(authCallback); | ||||
|         log.info("[thirdLogin][请求三方平台 type({}) request({}) response({})]", reqVO.getType(), JsonUtils.toJsonString(authCallback), | ||||
|                 JsonUtils.toJsonString(authResponse)); | ||||
|         if (!authResponse.ok()) { | ||||
|             throw new RuntimeException(""); // TODO 芋艿:补全 | ||||
|         } | ||||
|         AuthUser authUser = (AuthUser) authResponse.getData(); | ||||
|  | ||||
|         // 查找到对应的 | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     private void verifyCaptcha(String username, String captchaUUID, String captchaCode) { | ||||
|         String code = captchaService.getCaptchaCode(captchaUUID); | ||||
|         // 验证码不存在 | ||||
|   | ||||
| @@ -173,8 +173,12 @@ justauth: | ||||
|   type: | ||||
|     GITEE: | ||||
|       client-id: 6bb0b37a8a017e5e2dc4c34ca4756dcf80e8e392585e7035d3ede7a6db50426e | ||||
|       client-secret: f117b9de5e9267bcd48db83d4cb078ea8cf9a5d17cda83481e3d9090df3fa01d | ||||
|       client-secret: ba9f1f42e77be71f461b54da83b6f4b45a052dd7f93418f00f91f4e6934dfd1f | ||||
|       ignore-check-redirect-uri: true | ||||
| #      redirect-uri: http://127.0.0.1:48080/api/gitee/callback | ||||
|     DINGTALK: | ||||
|       client-id: dingvrnreaje3yqvzhxg | ||||
|       client-secret: i8E6iZyDvZj51JIb0tYsYfVQYOks9Cq1lgryEjFRqC79P3iJcrxEwT6Qk2QvLrLI | ||||
|       ignore-check-redirect-uri: true | ||||
|   cache: | ||||
|     type: default | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV