|
@@ -8,6 +8,7 @@ import cn.hutool.captcha.LineCaptcha;
|
|
|
import cn.hutool.extra.servlet.ServletUtil;
|
|
import cn.hutool.extra.servlet.ServletUtil;
|
|
|
import cn.hutool.extra.spring.SpringUtil;
|
|
import cn.hutool.extra.spring.SpringUtil;
|
|
|
import com.jeeplus.auth.model.LoginForm;
|
|
import com.jeeplus.auth.model.LoginForm;
|
|
|
|
|
+import com.jeeplus.auth.service.DingTalkAuthService;
|
|
|
import com.jeeplus.common.SecurityUtils;
|
|
import com.jeeplus.common.SecurityUtils;
|
|
|
import com.jeeplus.common.TokenProvider;
|
|
import com.jeeplus.common.TokenProvider;
|
|
|
import com.jeeplus.common.constant.CacheNames;
|
|
import com.jeeplus.common.constant.CacheNames;
|
|
@@ -75,6 +76,9 @@ public class LoginController {
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private RedisUtils redisUtils;
|
|
private RedisUtils redisUtils;
|
|
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private DingTalkAuthService dingTalkAuthService;
|
|
|
|
|
+
|
|
|
|
|
|
|
|
@PostMapping("/login")
|
|
@PostMapping("/login")
|
|
|
@ApiLog(value = "用户登录", type = LogTypeEnum.LOGIN)
|
|
@ApiLog(value = "用户登录", type = LogTypeEnum.LOGIN)
|
|
@@ -495,5 +499,145 @@ public class LoginController {
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取钉钉配置
|
|
|
|
|
+ */
|
|
|
|
|
+ @GetMapping("/sys/dingtalk/clientConfig")
|
|
|
|
|
+ @ApiOperation("获取钉钉配置")
|
|
|
|
|
+ public ResponseEntity dingTalkClientConfig(@RequestParam(required = false) String tenantId) {
|
|
|
|
|
+ String resolvedTenantId = StringUtils.defaultIfBlank(tenantId, "10009");
|
|
|
|
|
+ com.jeeplus.auth.config.DingTalkProperties.TenantConfig tenantConfig = dingTalkAuthService.getTenantConfig(resolvedTenantId);
|
|
|
|
|
+ return ResponseUtil.newInstance()
|
|
|
|
|
+ .add("tenantId", resolvedTenantId)
|
|
|
|
|
+ .add("corpId", tenantConfig.getCorpId())
|
|
|
|
|
+ .add("agentId", tenantConfig.getAgentId())
|
|
|
|
|
+ .ok();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 钉钉authCode登录
|
|
|
|
|
+ */
|
|
|
|
|
+ @PostMapping("/sys/dingtalk/login")
|
|
|
|
|
+ @ApiLog(value = "钉钉授权登录", type = LogTypeEnum.LOGIN)
|
|
|
|
|
+ @ApiOperation("钉钉授权登录")
|
|
|
|
|
+ public ResponseEntity dingTalkAuthCodeLogin(@RequestBody LoginForm loginForm) {
|
|
|
|
|
+ String tenantId = StringUtils.defaultIfBlank(loginForm.getTenantId(), "10009");
|
|
|
|
|
+ DingTalkAuthService.DingTalkUser dingTalkUser = dingTalkAuthService.getUserByAuthCode(tenantId, loginForm.getAuthCode());
|
|
|
|
|
+ UserDTO user = userApi.getByDdIdAndTenantId(dingTalkUser.getUserId(), tenantId);
|
|
|
|
|
+ if (user == null) {
|
|
|
|
|
+ String bindKey = dingTalkAuthService.createBindKey(tenantId, dingTalkUser.getUserId());
|
|
|
|
|
+ return ResponseUtil.newInstance()
|
|
|
|
|
+ .add("bindRequired", true)
|
|
|
|
|
+ .add("bindKey", bindKey)
|
|
|
|
|
+ .add("tenantId", tenantId)
|
|
|
|
|
+ .ok("DingTalk account is not bound");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ResponseUtil responseUtil = new ResponseUtil();
|
|
|
|
|
+ String loginUserName = user.getLoginName();
|
|
|
|
|
+ String username = user.getLoginName();
|
|
|
|
|
+ Object redisValue = RedisUtils.getInstance().get(CacheNames.USER_CACHE_LOGIN_CODE + loginUserName);
|
|
|
|
|
+ Integer redisLoginNumber = null;
|
|
|
|
|
+
|
|
|
|
|
+ if (redisValue != null) {
|
|
|
|
|
+ redisLoginNumber = Integer.valueOf(redisValue.toString());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ redisLoginNumber = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (null == redisLoginNumber) {
|
|
|
|
|
+ redisLoginNumber = 0;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ redisLoginNumber++;
|
|
|
|
|
+ }
|
|
|
|
|
+ RedisUtils.getInstance().set(CacheNames.USER_CACHE_LOGIN_CODE + loginUserName, redisLoginNumber);
|
|
|
|
|
+ LocalDateTime now = LocalDateTime.now();
|
|
|
|
|
+ LocalDateTime midnight = now.toLocalDate().plusDays(1).atStartOfDay();
|
|
|
|
|
+ long secondsUntilMidnight = Duration.between(now, midnight).getSeconds();
|
|
|
|
|
+ RedisUtils.getInstance().expire(CacheNames.USER_CACHE_LOGIN_CODE + loginUserName, secondsUntilMidnight);
|
|
|
|
|
+
|
|
|
|
|
+ Integer loginNumber = 5;
|
|
|
|
|
+ if (redisLoginNumber >= 10) {
|
|
|
|
|
+ return ResponseEntity.badRequest().body(ErrorConstants.LOGIN_MAX_COUNT);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (redisLoginNumber > loginNumber) {
|
|
|
|
|
+ return ResponseEntity.badRequest().body(ErrorConstants.LOGIN_CODE);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ AuthenticationManager authenticationManager = SpringUtil.getBean(AuthenticationManager.class);
|
|
|
|
|
+ SecurityUtils.login(username, "Xg@sys9hB2!xWm", authenticationManager);
|
|
|
|
|
+
|
|
|
|
|
+ String domain = RequestUtils.getHeader("domain");
|
|
|
|
|
+ if (domain != null && domain.contains("ydddl")) {
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (!userApi.isEnableLogin(tenantId, username)) {
|
|
|
|
|
+ throw new DisabledException(ErrorConstants.LOGIN_ERROR_FORBID_LOGGED_IN_ELSEWHERE);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ UserDTO userDTO = userApi.getByLoginName(username, tenantId);
|
|
|
|
|
+
|
|
|
|
|
+ if ("妯婅帀".equals(userDTO.getName())) {
|
|
|
|
|
+
|
|
|
|
|
+ List<UserDTO> onLineUserList = SpringUtil.getBean(IUserApi.class).getOnLineUserList("榛勭幃", "10002");
|
|
|
|
|
+ if (!onLineUserList.isEmpty()) {
|
|
|
|
|
+ throw new DisabledException("褰撳墠榛勭幃宸茬櫥褰曠郴缁燂紝" + ErrorConstants.LOGIN_ERROR);
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if ("榛勭幃".equals(userDTO.getName())) {
|
|
|
|
|
+ List<UserDTO> onLineUserList = SpringUtil.getBean(IUserApi.class).getOnLineUserList("妯婅帀", "10002");
|
|
|
|
|
+ if (!onLineUserList.isEmpty()) {
|
|
|
|
|
+ throw new DisabledException("褰撳墠妯婅帀宸茬櫥褰曠郴缁燂紝" + ErrorConstants.LOGIN_ERROR);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ String token = TokenProvider.createAccessToken(username);
|
|
|
|
|
+ responseUtil.add(TokenProvider.TOKEN, token);
|
|
|
|
|
+ updateUserLoginInfo(responseUtil, userDTO, token);
|
|
|
|
|
+
|
|
|
|
|
+ RedisUtils.getInstance().delete(CacheNames.USER_CACHE_LOGIN_CODE + loginUserName);
|
|
|
|
|
+
|
|
|
|
|
+ userDTO.setToken(token);
|
|
|
|
|
+ return responseUtil.ok();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 将当前的钉钉用户绑定到系统账户,然后登录。
|
|
|
|
|
+ */
|
|
|
|
|
+ @PostMapping("/sys/dingtalk/bindLogin")
|
|
|
|
|
+ @ApiLog(value = "钉钉授权并绑定用户进行登录", type = LogTypeEnum.LOGIN)
|
|
|
|
|
+ @ApiOperation("钉钉授权并绑定用户进行登录")
|
|
|
|
|
+ public ResponseEntity dingTalkBindLogin(@RequestBody LoginForm loginForm) {
|
|
|
|
|
+ DingTalkAuthService.BindInfo bindInfo = dingTalkAuthService.getBindInfo(loginForm.getDingTalkBindKey());
|
|
|
|
|
+ String username = loginForm.getUsername();
|
|
|
|
|
+ String password = loginForm.getPassword();
|
|
|
|
|
+
|
|
|
|
|
+ AuthenticationManager authenticationManager = SpringUtil.getBean(AuthenticationManager.class);
|
|
|
|
|
+ SecurityUtils.login(username, password, authenticationManager);
|
|
|
|
|
+
|
|
|
|
|
+ UserDTO userDTO = userApi.getByLoginName(username, bindInfo.getTenantId());
|
|
|
|
|
+ if (userDTO == null) {
|
|
|
|
|
+ throw new UsernameNotFoundException(ErrorConstants.LOGIN_ERROR_NOTFOUND);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (CommonConstants.NO.equals(userDTO.getLoginFlag())) {
|
|
|
|
|
+ throw new LockedException(ErrorConstants.LOGIN_ERROR_FORBIDDEN);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (StringUtils.isNotBlank(userDTO.getDdId()) && !bindInfo.getDdId().equals(userDTO.getDdId())) {
|
|
|
|
|
+ return ResponseEntity.badRequest().body("Current system account is already bound to another DingTalk account");
|
|
|
|
|
+ }
|
|
|
|
|
+ UserDTO bindUserDTO = new UserDTO();
|
|
|
|
|
+ bindUserDTO.setId(userDTO.getId());
|
|
|
|
|
+ bindUserDTO.setDdId(bindInfo.getDdId());
|
|
|
|
|
+ userApi.updateUserById(bindUserDTO);
|
|
|
|
|
+ userDTO.setDdId(bindInfo.getDdId());
|
|
|
|
|
+ userApi.clearCache(userDTO);
|
|
|
|
|
+ dingTalkAuthService.removeBindKey(loginForm.getDingTalkBindKey());
|
|
|
|
|
+
|
|
|
|
|
+ ResponseUtil responseUtil = new ResponseUtil();
|
|
|
|
|
+ String token = TokenProvider.createAccessToken(username);
|
|
|
|
|
+ responseUtil.add(TokenProvider.TOKEN, token);
|
|
|
|
|
+ updateUserLoginInfo(responseUtil, userDTO, token);
|
|
|
|
|
+ return responseUtil.ok();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
|
|
|
}
|
|
}
|