mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-08-06 22:31:53 +08:00
增加三方登陆的 redirect uri
This commit is contained in:
@@ -41,7 +41,7 @@ public class InfFileController {
|
||||
@ApiOperation("上传文件")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "file", value = "文件附件", required = true, dataTypeClass = MultipartFile.class),
|
||||
@ApiImplicitParam(name = "path", value = "文件路径", required = false, example = "yudaoyuanma.png", dataTypeClass = String.class)
|
||||
@ApiImplicitParam(name = "path", value = "文件路径", example = "yudaoyuanma.png", dataTypeClass = String.class)
|
||||
})
|
||||
public CommonResult<String> uploadFile(@RequestParam("file") MultipartFile file,
|
||||
@RequestParam("path") String path) throws IOException {
|
||||
|
@@ -1,8 +1,13 @@
|
||||
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;
|
||||
@@ -18,15 +23,31 @@ import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermiss
|
||||
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.util.collection.SetUtils;
|
||||
import com.aliyuncs.CommonResponse;
|
||||
import com.xkcoding.justauth.AuthRequestFactory;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
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 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;
|
||||
@@ -39,6 +60,7 @@ import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getUse
|
||||
@RestController
|
||||
@RequestMapping("/")
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class SysAuthController {
|
||||
|
||||
@Resource
|
||||
@@ -52,6 +74,9 @@ public class SysAuthController {
|
||||
@Resource
|
||||
private SysUserSessionService sysUserSessionService;
|
||||
|
||||
@Resource
|
||||
private AuthRequestFactory authRequestFactory;
|
||||
|
||||
@PostMapping("/login")
|
||||
@ApiOperation("使用账号密码登录")
|
||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||
@@ -61,17 +86,42 @@ public class SysAuthController {
|
||||
return success(SysAuthLoginRespVO.builder().token(token).build());
|
||||
}
|
||||
|
||||
@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("/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() {
|
||||
|
@@ -1,31 +1,26 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.system.convert.auth;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user.SysUserCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.enums.common.SysSexEnum;
|
||||
import cn.iocoder.yudao.framework.security.core.Auth2LoginUser;
|
||||
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||
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.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;
|
||||
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.MenuIdEnum;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import me.zhyd.oauth.enums.AuthUserGender;
|
||||
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||
import me.zhyd.oauth.model.AuthUser;
|
||||
import org.mapstruct.*;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
@Mapper(uses = SysAuthConvert.UserSexTransform.class)
|
||||
@Mapper
|
||||
public interface SysAuthConvert {
|
||||
|
||||
SysAuthConvert INSTANCE = Mappers.getMapper(SysAuthConvert.class);
|
||||
@@ -33,7 +28,6 @@ public interface SysAuthConvert {
|
||||
@Mapping(source = "updateTime", target = "updateTime", ignore = true)
|
||||
// 字段相同,但是含义不同,忽略
|
||||
LoginUser convert(SysUserDO bean);
|
||||
Auth2LoginUser getAuth2LoginUser(SysUserDO bean);
|
||||
|
||||
default SysAuthPermissionInfoRespVO convert(SysUserDO user, List<SysRoleDO> roleList, List<SysMenuDO> menuList) {
|
||||
return SysAuthPermissionInfoRespVO.builder()
|
||||
@@ -49,16 +43,6 @@ public interface SysAuthConvert {
|
||||
|
||||
LoginUser convert(SysUserProfileUpdatePasswordReqVO reqVO);
|
||||
|
||||
@Mappings(
|
||||
@Mapping(target = "sex", source = "gender")
|
||||
)
|
||||
SysUserCreateReqVO convert(AuthUser authUser);
|
||||
|
||||
@Mappings(
|
||||
@Mapping(target = "thirdPartyUserId", source = "uuid")
|
||||
)
|
||||
Auth2LoginUser getLoginUser(AuthUser authUser);
|
||||
|
||||
/**
|
||||
* 将菜单列表,构建成菜单树
|
||||
*
|
||||
@@ -91,24 +75,4 @@ public interface SysAuthConvert {
|
||||
return CollectionUtils.filterList(treeNodeMap.values(), node -> MenuIdEnum.ROOT.getId().equals(node.getParentId()));
|
||||
}
|
||||
|
||||
public class UserSexTransform {
|
||||
|
||||
public int toInt (AuthUserGender gender){
|
||||
switch (gender) {
|
||||
case MALE:
|
||||
return SysSexEnum.MALE.getSex();
|
||||
case FEMALE:
|
||||
return SysSexEnum.FEMALE.getSex();
|
||||
default:
|
||||
return SysSexEnum.UNKNOWN.getSex();
|
||||
}
|
||||
}
|
||||
|
||||
public AuthUserGender strToBoolean(int sex){
|
||||
if(sex == SysSexEnum.UNKNOWN.getSex()) {
|
||||
return AuthUserGender.UNKNOWN;
|
||||
}
|
||||
return AuthUserGender.getRealGender(String.valueOf(sex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,19 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.system.convert.auth.config;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.system.convert.auth.handler.DefaultSignUpUrlAuthenticationSuccessHandler;
|
||||
import cn.iocoder.yudao.framework.security.core.handler.AbstractSignUpUrlAuthenticationSuccessHandler;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author weir
|
||||
*/
|
||||
@Configuration
|
||||
public class AuthConfig {
|
||||
@Bean
|
||||
public AbstractSignUpUrlAuthenticationSuccessHandler authenticationSuccessHandler() {
|
||||
AbstractSignUpUrlAuthenticationSuccessHandler successHandler = new DefaultSignUpUrlAuthenticationSuccessHandler();
|
||||
successHandler.setDefaultTargetUrl("/api/callback");
|
||||
return successHandler;
|
||||
}
|
||||
}
|
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
* Copyright (c) 2020-2029 YongWu zheng (dcenter.top and gitee.com/pcore and github.com/ZeroOrInfinity)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package cn.iocoder.yudao.adminserver.modules.system.convert.auth.handler;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthLoginRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.auth.SysUserSessionService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.security.core.Auth2LoginUser;
|
||||
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||
import cn.iocoder.yudao.framework.security.core.handler.AbstractSignUpUrlAuthenticationSuccessHandler;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.DefaultRedirectStrategy;
|
||||
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
|
||||
import org.springframework.security.web.savedrequest.RequestCache;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
|
||||
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getUserAgent;
|
||||
import static java.util.Collections.singleton;
|
||||
import static top.dcenter.ums.security.core.oauth.util.MvcUtil.*;
|
||||
|
||||
/**
|
||||
* @author weir
|
||||
*/
|
||||
public class DefaultSignUpUrlAuthenticationSuccessHandler extends AbstractSignUpUrlAuthenticationSuccessHandler {
|
||||
private RequestCache requestCache = new HttpSessionRequestCache();
|
||||
@Autowired
|
||||
private SysUserSessionService userSessionService;
|
||||
@Resource
|
||||
private SysPermissionService permissionService;
|
||||
|
||||
@Override
|
||||
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
|
||||
final Object principal = authentication.getPrincipal();
|
||||
String token = userSessionService.createUserSession(defaultHandleUserRoles((LoginUser) principal), getClientIP(), getUserAgent());
|
||||
if(StringUtils.isNotBlank(token)) {
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
}
|
||||
if (principal instanceof Auth2LoginUser) {
|
||||
new DefaultRedirectStrategy().sendRedirect(request, response, getUrl() + token);
|
||||
return;
|
||||
}
|
||||
if (isAjaxOrJson(request)) {
|
||||
responseWithJson(response, HttpStatus.OK.value(), toJsonString(success(SysAuthLoginRespVO.builder().token(token).build())));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
requestCache.saveRequest(request, response);
|
||||
super.setRequestCache(requestCache);
|
||||
super.onAuthenticationSuccess(request, response, authentication);
|
||||
} catch (ServletException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getUrl() {
|
||||
// return "http://localhost/oauthLogin/gitee?token=";
|
||||
return "http://127.0.0.1:1024/oauthLogin/gitee?token=";
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认处理方式处理用户角色列表;建议角色权限前置到 UserDetails
|
||||
*
|
||||
* @param loginUser 用户
|
||||
* @return
|
||||
*/
|
||||
private LoginUser defaultHandleUserRoles(LoginUser loginUser) {
|
||||
Set<Long> roleIds = loginUser.getRoleIds();
|
||||
if (roleIds == null || roleIds.isEmpty()) {
|
||||
Set<Long> userRoleIds = permissionService.getUserRoleIds(loginUser.getId(), singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
loginUser.setRoleIds(userRoleIds);
|
||||
}
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequestCache(RequestCache requestCache) {
|
||||
this.requestCache = requestCache;
|
||||
}
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.social;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import me.zhyd.oauth.model.AuthUser;
|
||||
|
||||
/**
|
||||
* @author weir
|
||||
*/
|
||||
@Data
|
||||
@TableName("user_connection")
|
||||
public class SocialUserDO extends AuthUser {
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.social;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 系统用户和第三方用户关联表
|
||||
* @author weir
|
||||
*/
|
||||
@TableName("sys_user_social")
|
||||
@Data
|
||||
public class SysUserSocialDO extends BaseDO {
|
||||
/**
|
||||
* 自增主键
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 用户 ID
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 角色 ID
|
||||
*/
|
||||
private String socialUserId;
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,75 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.system.enums.user.SysUserSocialTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
* 三方登陆信息
|
||||
* 通过 {@link SysUserSocialDO#getUserId()} 关联到对应的 {@link SysUserDO}
|
||||
*
|
||||
* @author weir
|
||||
*/
|
||||
@TableName(value = "sys_user_social", autoResultMap = true)
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SysUserSocialDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 自增主键
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 用户类型
|
||||
*
|
||||
* 枚举 {@link UserTypeEnum}
|
||||
*/
|
||||
private Integer userType;
|
||||
|
||||
/**
|
||||
* 三方平台的类型
|
||||
*/
|
||||
private SysUserSocialTypeEnum type;
|
||||
/**
|
||||
* 三方 openid
|
||||
*/
|
||||
private String openid;
|
||||
/**
|
||||
* 三方 token
|
||||
*/
|
||||
private String token;
|
||||
/**
|
||||
* 三方的全局编号
|
||||
*
|
||||
* 例如说,微信平台的 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/union-id.html
|
||||
* 如果没有 unionId 的平台,直接使用 openid 作为该字段的值
|
||||
*/
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 原始数据,一般是 JSON 格式
|
||||
*/
|
||||
private String info;
|
||||
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.system.dal.mysql.social;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.social.SysUserSocialDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserSocialDO;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.system.dal.mysql.social;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.social.SysUserSocialDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserSocialDO;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
|
@@ -0,0 +1,44 @@
|
||||
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 jodd.util.ArraysUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 用户的三方平台的类型枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum SysUserSocialTypeEnum implements IntArrayValuable {
|
||||
|
||||
GITEE(10, "GITEE"), // https://gitee.com/api/v5/oauth_doc#/
|
||||
;
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SysUserSocialTypeEnum::getType).toArray();
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final Integer type;
|
||||
/**
|
||||
* 类型的标识
|
||||
*/
|
||||
private final String source;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static SysUserSocialTypeEnum valueOfType(Integer type) {
|
||||
return ArrayUtil.firstMatch(o -> o.getType().equals(type), values());
|
||||
}
|
||||
|
||||
}
|
@@ -1,237 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
* Copyright (c) 2020-2029 YongWu zheng (dcenter.top and gitee.com/pcore and github.com/ZeroOrInfinity)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package cn.iocoder.yudao.adminserver.modules.system.service.auth.impl;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user.SysUserCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.convert.auth.SysAuthConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO;
|
||||
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.security.core.Auth2LoginUser;
|
||||
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||
import com.google.common.collect.Sets;
|
||||
import me.zhyd.oauth.model.AuthUser;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserCache;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import top.dcenter.ums.security.core.oauth.enums.ErrorCodeEnum;
|
||||
import top.dcenter.ums.security.core.oauth.exception.RegisterUserFailureException;
|
||||
import top.dcenter.ums.security.core.oauth.exception.UserNotExistException;
|
||||
import top.dcenter.ums.security.core.oauth.service.UmsUserDetailsService;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 用户密码与手机短信登录与注册服务:<br><br>
|
||||
* 1. 用于第三方登录与手机短信登录逻辑。<br><br>
|
||||
* 2. 用于用户密码登录逻辑。<br><br>
|
||||
* 3. 用户注册逻辑。<br><br>
|
||||
* @author YongWu zheng
|
||||
* @version V1.0 Created by 2020/9/20 11:06
|
||||
*/
|
||||
@Service
|
||||
public class UserDetailsServiceImpl implements UmsUserDetailsService {
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
|
||||
@Autowired(required = false)
|
||||
private UserCache userCache;
|
||||
|
||||
@Resource
|
||||
private SysUserService userService;
|
||||
|
||||
/**
|
||||
* 用于密码加解密
|
||||
*/
|
||||
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
@Autowired
|
||||
private SysPermissionService permissionService;
|
||||
|
||||
@SuppressWarnings("AlibabaUndefineMagicConstant")
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
|
||||
try
|
||||
{
|
||||
// 从缓存中查询用户信息:
|
||||
// 从缓存中查询用户信息
|
||||
if (this.userCache != null)
|
||||
{
|
||||
UserDetails userDetails = this.userCache.getUserFromCache(username);
|
||||
if (userDetails != null)
|
||||
{
|
||||
return userDetails;
|
||||
}
|
||||
}
|
||||
// 根据用户名获取用户信息
|
||||
// 获取 username 对应的 SysUserDO
|
||||
SysUserDO user = userService.getUserByUsername(username);
|
||||
if (user == null) {
|
||||
throw new UsernameNotFoundException(username);
|
||||
}
|
||||
// 创建 LoginUser 对象
|
||||
Auth2LoginUser loginUser = SysAuthConvert.INSTANCE.getAuth2LoginUser(user);
|
||||
//TODO 登录日志等可以和用户名密码等兼容处理
|
||||
return loginUser;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
String msg = String.format("第三方登录 ======>: 登录用户名:%s, 登录失败: %s", username, e.getMessage());
|
||||
log.error(msg);
|
||||
throw new UserNotExistException(ErrorCodeEnum.QUERY_USER_INFO_ERROR, e, username);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails registerUser(@NonNull AuthUser authUser, @NonNull String username,
|
||||
@NonNull String defaultAuthority, String decodeState) throws RegisterUserFailureException {
|
||||
|
||||
// 这里的 decodeState 可以根据自己实现的 top.dcenter.ums.security.core.oauth.service.Auth2StateCoder 接口的逻辑来传递必要的参数.
|
||||
// 比如: 第三方登录成功后的跳转地址
|
||||
final RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
|
||||
// 假设 decodeState 就是 redirectUrl, 我们直接把 redirectUrl 设置到 request 上
|
||||
// 后续经过成功处理器时直接从 requestAttributes.getAttribute("redirectUrl", RequestAttributes.SCOPE_REQUEST) 获取并跳转
|
||||
if (requestAttributes != null) {
|
||||
requestAttributes.setAttribute("redirectUrl", decodeState, RequestAttributes.SCOPE_REQUEST);
|
||||
}
|
||||
//返回用户
|
||||
LoginUser loginUser = doRegistUser(authUser);
|
||||
|
||||
log.info("第三方用户注册 ======>: 用户名:{}, 注册成功", username);
|
||||
|
||||
// 把用户信息存入缓存
|
||||
if (userCache != null)
|
||||
{
|
||||
userCache.putUserInCache(loginUser);
|
||||
}
|
||||
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
private LoginUser doRegistUser(AuthUser authUser) {
|
||||
SysUserCreateReqVO reqVO = SysAuthConvert.INSTANCE.convert(authUser);
|
||||
if (StringUtils.isEmpty(reqVO.getPassword())) {
|
||||
reqVO.setPassword(getDefaultPassword());
|
||||
}
|
||||
//添加用户
|
||||
Long sysUserId = userService.createUser(reqVO);
|
||||
//关联第三方用户
|
||||
Long userId = userService.bindSocialUSer(sysUserId, authUser.getUuid());
|
||||
//赋予默认角色权限;三方登录默认部分
|
||||
permissionService.assignUserRole(userId, getDefaultRoles());
|
||||
LoginUser loginUser = SysAuthConvert.INSTANCE.getLoginUser(authUser);
|
||||
loginUser.setRoleIds(getDefaultRoles());
|
||||
loginUser.setPassword(getDefaultPassword());
|
||||
loginUser.setId(sysUserId);
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
private String getDefaultPassword() {
|
||||
return "123456";
|
||||
}
|
||||
|
||||
protected Set<Long> getDefaultRoles() {
|
||||
return Sets.newHashSet(1L);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public UserDetails registerUser(@NonNull String mobile, Map<String, String> otherParamMap) throws RegisterUserFailureException {
|
||||
|
||||
// 用户信息持久化逻辑。。。
|
||||
// ...
|
||||
|
||||
log.info("Demo ======>: 手机短信登录用户 {}:注册成功", mobile);
|
||||
|
||||
User user = new User(mobile,
|
||||
passwordEncoder.encode("admin"),
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
AuthorityUtils.commaSeparatedStringToAuthorityList("admin, ROLE_USER")
|
||||
);
|
||||
|
||||
// 把用户信息存入缓存
|
||||
if (userCache != null)
|
||||
{
|
||||
userCache.putUserInCache(user);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link #existedByUsernames(String...)} usernames 生成规则.
|
||||
* 如需自定义重新实现此逻辑
|
||||
* @param authUser 第三方用户信息
|
||||
* @return 返回一个 username 数组
|
||||
*/
|
||||
@Override
|
||||
public String[] generateUsernames(AuthUser authUser) {
|
||||
return new String[]{
|
||||
authUser.getUsername(),
|
||||
// providerId = authUser.getSource()
|
||||
authUser.getUsername() + "_" + authUser.getSource(),
|
||||
// providerUserId = authUser.getUuid()
|
||||
authUser.getUsername() + "_" + authUser.getSource() + "_" + authUser.getUuid()
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUserId(String userId) throws UsernameNotFoundException {
|
||||
UserDetails userDetails = loadUserByUsername(userId);
|
||||
User.withUserDetails(userDetails);
|
||||
return userDetails;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Boolean> existedByUsernames(String... usernames) throws UsernameNotFoundException {
|
||||
// ... 在本地账户上查询 userIds 是否已被使用
|
||||
List<Boolean> list = new ArrayList<>();
|
||||
for (String username : usernames) {
|
||||
SysUserDO userDO = userService.getUserByUsername(username);
|
||||
list.add(userDO != null);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
@@ -4,7 +4,7 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.social.SysUserSocialDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserSocialDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.mysql.social.SysUserSocialMapper;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||
@@ -82,7 +82,7 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
public Long bindSocialUSer(Long sysUserId, String socialUSerId) {
|
||||
SysUserSocialDO userSocialDO = new SysUserSocialDO();
|
||||
userSocialDO.setUserId(sysUserId);
|
||||
userSocialDO.setSocialUserId(socialUSerId);
|
||||
// userSocialDO.setSocialUserId(socialUSerId);
|
||||
userSocialMapper.insert(userSocialDO);
|
||||
return userSocialDO.getUserId();
|
||||
}
|
||||
|
Reference in New Issue
Block a user