|
|
@@ -8,11 +8,14 @@ import com.uas.sso.SSOToken;
|
|
|
import com.uas.sso.common.util.HttpUtil;
|
|
|
import com.uas.sso.core.Const;
|
|
|
import com.uas.sso.entity.App;
|
|
|
+import com.uas.sso.entity.User;
|
|
|
import com.uas.sso.entity.UserAccount;
|
|
|
+import com.uas.sso.entity.UserRecord;
|
|
|
import com.uas.sso.service.AppService;
|
|
|
import com.uas.sso.service.UserService;
|
|
|
import com.uas.sso.service.impl.UserAccountService;
|
|
|
import com.uas.sso.util.AccountTypeUtils;
|
|
|
+import com.uas.sso.util.CaptchaUtil;
|
|
|
import com.uas.sso.web.waf.request.WafRequestWrapper;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.ui.ModelMap;
|
|
|
@@ -20,9 +23,10 @@ import org.springframework.util.CollectionUtils;
|
|
|
import org.springframework.util.StringUtils;
|
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
import org.springframework.web.bind.annotation.RequestMethod;
|
|
|
-import org.springframework.web.bind.annotation.ResponseBody;
|
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
|
|
|
|
+import javax.servlet.ServletException;
|
|
|
+import java.io.IOException;
|
|
|
import java.util.*;
|
|
|
|
|
|
/**
|
|
|
@@ -35,6 +39,21 @@ import java.util.*;
|
|
|
@RestController
|
|
|
public class LoginController extends BaseController {
|
|
|
|
|
|
+ /**
|
|
|
+ * 密码输错3次
|
|
|
+ */
|
|
|
+ private static final int PWD_ERROR_FIVE_TIME = 5;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 密码输错3次
|
|
|
+ */
|
|
|
+ private static final int PWD_ERROR_THREE_TIME = 3;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 登录验证码存session的key值
|
|
|
+ */
|
|
|
+ private static final String LOGIN_CAPTCHA = "loginCaptcha";
|
|
|
+
|
|
|
@Autowired
|
|
|
private AppService appService;
|
|
|
|
|
|
@@ -45,7 +64,6 @@ public class LoginController extends BaseController {
|
|
|
private UserAccountService userAccountService;
|
|
|
|
|
|
@RequestMapping(method = RequestMethod.POST)
|
|
|
- @ResponseBody
|
|
|
public ModelMap login() {
|
|
|
// 获取登录信息
|
|
|
WafRequestWrapper wr = new WafRequestWrapper(request);
|
|
|
@@ -53,6 +71,7 @@ public class LoginController extends BaseController {
|
|
|
String spaceUU = wr.getParameter("spaceUU");
|
|
|
String username = StringUtils.trimAllWhitespace(wr.getParameter("username"));
|
|
|
String password = wr.getParameter("password");
|
|
|
+ String captcha = wr.getParameter("captcha");
|
|
|
String returnUrl = wr.getParameter("returnUrl");
|
|
|
String baseUrl = wr.getParameter("baseUrl");
|
|
|
|
|
|
@@ -76,6 +95,34 @@ public class LoginController extends BaseController {
|
|
|
return error("应用id不存在");
|
|
|
}
|
|
|
|
|
|
+ // 获取用户基本信息
|
|
|
+ User user = userService.findByUsername(username);
|
|
|
+ if (user == null) {
|
|
|
+ return error("用户名或密码错误");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验账户密码输错次数
|
|
|
+ int pwdErrorCount = user.getUserRecord() == null ? 0 : user.getUserRecord().getPwdErrorCount();
|
|
|
+ Object loginCaptcha = request.getSession().getAttribute(LOGIN_CAPTCHA);
|
|
|
+ String checkCode = loginCaptcha == null ? "" : loginCaptcha.toString();
|
|
|
+ if (pwdErrorCount >= PWD_ERROR_FIVE_TIME) {
|
|
|
+ return error("403", "密码错误次数已达上限,今日无法登陆");
|
|
|
+ }
|
|
|
+ // 校验账号是否被锁定,5次输错密码
|
|
|
+ if (pwdErrorCount >= PWD_ERROR_THREE_TIME && StringUtils.isEmpty(captcha)) {
|
|
|
+ return error("404", "验证码不能为空");
|
|
|
+ }
|
|
|
+ if (pwdErrorCount >= PWD_ERROR_THREE_TIME && !captcha.equalsIgnoreCase(checkCode)) {
|
|
|
+ return error("验证码错误");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验密码
|
|
|
+ String encryPwd = userService.getEncryPassword(Const.ENCRY_FORMAT, password, user.getSalt());
|
|
|
+ if (!encryPwd.equals(user.getPassword())) {
|
|
|
+ pwdErrorCount = inputErrorPwd(user.getUserRecord());
|
|
|
+ return error("您输入的账号或密码有误").addAttribute("errorCount", pwdErrorCount);
|
|
|
+ }
|
|
|
+
|
|
|
// 登录
|
|
|
App controlApp = StringUtils.isEmpty(app.getUserControl()) ? app : appService.findOne(app.getUserControl());
|
|
|
boolean personalEnable = Const.YES == controlApp.getPersonalEnable();
|
|
|
@@ -83,26 +130,16 @@ public class LoginController extends BaseController {
|
|
|
if (StringUtils.isEmpty(spaceUU)) {
|
|
|
/*企业uu号为空,让用户选择企业*/
|
|
|
// 找到用户账号信息
|
|
|
- List<UserAccount> userAccounts = getUserAccountByUserName(controlApp.getUid(), username);
|
|
|
+ List<UserAccount> userAccounts = userAccountService.findByUserUU(appId, user.getUserUU());
|
|
|
|
|
|
- // 应用不允许个人账号,并且账号未绑定企业
|
|
|
- if (!personalEnable && CollectionUtils.isEmpty(userAccounts)) {
|
|
|
- return error("用户名或密码错误");
|
|
|
+ // 没有记录
|
|
|
+ if (CollectionUtils.isEmpty(userAccounts)) {
|
|
|
+ return error("您的账号为绑定企业并且当前应用不支持个人账号");
|
|
|
}
|
|
|
|
|
|
// 应用允许个人账号,并且账号未绑定企业,或者只绑定了一个企业,直接登录
|
|
|
if (userAccounts.size() == 1) {
|
|
|
- return loginByUser(userAccounts.get(0), password, returnUrl);
|
|
|
- }
|
|
|
-
|
|
|
- // 由于老账户存在多个账号绑定一个邮箱的情况,把密码不符合的企业去除
|
|
|
- Iterator<UserAccount> iterator = userAccounts.iterator();
|
|
|
- while (iterator.hasNext()) {
|
|
|
- UserAccount userAccount = iterator.next();
|
|
|
- String encryPwd = userService.getEncryPassword(Const.ENCRY_FORMAT, password, userAccount.getSalt());
|
|
|
- if (!encryPwd.equals(userAccount.getPassword())) {
|
|
|
- iterator.remove();
|
|
|
- }
|
|
|
+ return loginByUser(userAccounts.get(0), returnUrl, user.getUserRecord());
|
|
|
}
|
|
|
|
|
|
// 返回企业id和名称
|
|
|
@@ -110,14 +147,37 @@ public class LoginController extends BaseController {
|
|
|
} else if (spaceUU.equals(Const.SPACEUU_PERSONAL)) {
|
|
|
// 使用个人账号登录
|
|
|
UserAccount userAccount = getUserAccountByUserName(controlApp.getUid(), username, null);
|
|
|
- return loginByUser(userAccount, password, returnUrl);
|
|
|
+ return loginByUser(userAccount, returnUrl, user.getUserRecord());
|
|
|
} else {
|
|
|
// 带企业登录
|
|
|
UserAccount userAccount = getUserAccountByUserName(controlApp.getUid(), username, spaceUU);
|
|
|
- return loginByUser(userAccount, password, returnUrl);
|
|
|
+ return loginByUser(userAccount, returnUrl, user.getUserRecord());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 密码输错处理
|
|
|
+ *
|
|
|
+ * @param userRecord 用户登录记录
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private int inputErrorPwd(UserRecord userRecord) {
|
|
|
+ // 密码输错次数+1
|
|
|
+ int pwdErrorCount = userRecord.getPwdErrorCount();
|
|
|
+ userRecord.setPwdErrorCount(++pwdErrorCount);
|
|
|
+ userService.save(userRecord);
|
|
|
+
|
|
|
+ // 设置返回值
|
|
|
+ return pwdErrorCount;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据用户名获得用户账号信息
|
|
|
+ *
|
|
|
+ * @param appId 应用
|
|
|
+ * @param username 用户名
|
|
|
+ * @return
|
|
|
+ */
|
|
|
private List<UserAccount> getUserAccountByUserName(String appId, String username) {
|
|
|
String type = AccountTypeUtils.getAccountType(username);
|
|
|
if (AccountTypeUtils.MOBILE.equals(type)) {
|
|
|
@@ -130,13 +190,21 @@ public class LoginController extends BaseController {
|
|
|
}
|
|
|
if (AccountTypeUtils.UU_NUMBER.equals(type)) {
|
|
|
// uu号登录
|
|
|
- return userAccountService.findOneByUserUU(appId, Long.valueOf(username));
|
|
|
+ return userAccountService.findByUserUU(appId, Long.valueOf(username));
|
|
|
}
|
|
|
|
|
|
// 其余情况
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 根据用户名和企业uu找到用户信息
|
|
|
+ *
|
|
|
+ * @param appId 应用
|
|
|
+ * @param username 用户名
|
|
|
+ * @param spaceUU 企业uu号
|
|
|
+ * @return
|
|
|
+ */
|
|
|
private UserAccount getUserAccountByUserName(String appId, String username, String spaceUU) {
|
|
|
String type = AccountTypeUtils.getAccountType(username);
|
|
|
if (AccountTypeUtils.MOBILE.equals(type)) {
|
|
|
@@ -156,38 +224,37 @@ public class LoginController extends BaseController {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- private ModelMap loginByUser(UserAccount userAccount, String password, String returnUrl) {
|
|
|
- if (StringUtils.isEmpty((userAccount.getPassword()))) {
|
|
|
- // 使用错误码100来判断
|
|
|
- return error("100", "未设置密码");
|
|
|
- } else {
|
|
|
- // 校验密码
|
|
|
- String encryPwd = userService.getEncryPassword(Const.ENCRY_FORMAT, password, userAccount.getSalt());
|
|
|
- if (!encryPwd.equals(userAccount.getPassword())) {
|
|
|
- return error("您输入的账号或密码有误");
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 用户信息没问题,直接登录
|
|
|
+ *
|
|
|
+ * @param userAccount 用户账号信息
|
|
|
+ * @param returnUrl 跳转url
|
|
|
+ * @param userRecord 用户登录记录,便于记录登录时间,不能直接new出来
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private ModelMap loginByUser(UserAccount userAccount, String returnUrl, UserRecord userRecord) {
|
|
|
+ /*
|
|
|
+ * 设置登录 Cookie 最后一个参数 true 时添加 cookie 同时销毁当前 JSESSIONID
|
|
|
+ * 创建信任的 JSESSIONID
|
|
|
+ */
|
|
|
+ SSOToken st = new SSOToken(request, userAccount.getMobile());
|
|
|
+ st.setData(JSON.toJSONString(userAccount));
|
|
|
+ SSOHelper.setSSOCookie(request, response, st, true);
|
|
|
|
|
|
- // 登录
|
|
|
- /*
|
|
|
- * 设置登录 Cookie 最后一个参数 true 时添加 cookie 同时销毁当前 JSESSIONID
|
|
|
- * 创建信任的 JSESSIONID
|
|
|
- */
|
|
|
- SSOToken st = new SSOToken(request, userAccount.getMobile());
|
|
|
- st.setData(JSON.toJSONString(userAccount));
|
|
|
- SSOHelper.setSSOCookie(request, response, st, true);
|
|
|
-
|
|
|
- // 通知各个应用用户已经登录
|
|
|
- ModelMap data = new ModelMap();
|
|
|
- data = addOtherAppRequestData(userAccount, data, request.getSession().getAttribute("baseUrl"), true);
|
|
|
- data.put("returnUrl", HttpUtil.decodeURL(returnUrl));
|
|
|
- return success(data);
|
|
|
- }
|
|
|
+ // 设置登录时间,并将密码输错次数设为0
|
|
|
+ userRecord.setLastLoginTime(System.currentTimeMillis());
|
|
|
+ userRecord.setPwdErrorCount(0);
|
|
|
+ userService.save(userRecord);
|
|
|
+
|
|
|
+ // 设置返回值,通知各个应用用户已经登录
|
|
|
+ ModelMap data = new ModelMap();
|
|
|
+ data = addOtherAppRequestData(userAccount, data, request.getSession().getAttribute("baseUrl"), true);
|
|
|
+ data.put("returnUrl", HttpUtil.decodeURL(returnUrl));
|
|
|
+ return success(data);
|
|
|
}
|
|
|
|
|
|
private ModelMap addOtherAppRequestData(UserAccount userAccount, ModelMap data, Object loginUrl,
|
|
|
boolean isLoginAll) {
|
|
|
- // 需要通知的应用数量
|
|
|
- int count = 0;
|
|
|
List<App> apps = appService.findAll();
|
|
|
List<String> loginUrls = new ArrayList<>();
|
|
|
boolean hasLoginUrl = false;
|
|
|
@@ -200,17 +267,14 @@ public class LoginController extends BaseController {
|
|
|
hasLoginUrl = true;
|
|
|
}
|
|
|
loginUrls.add(app.getLoginUrl());
|
|
|
- count++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 添加baseUrl
|
|
|
if (!hasLoginUrl && !StringUtils.isEmpty(loginUrl)) {
|
|
|
loginUrls.add(loginUrl.toString());
|
|
|
- count++;
|
|
|
}
|
|
|
|
|
|
- data.put("count", count);
|
|
|
data.put("loginUrls", loginUrls);
|
|
|
|
|
|
// 添加传递数据
|
|
|
@@ -247,4 +311,29 @@ public class LoginController extends BaseController {
|
|
|
return new ModelMap("spaces", spaces);
|
|
|
}
|
|
|
|
|
|
+ @RequestMapping(value = "/checkCode", method = RequestMethod.GET)
|
|
|
+ public void checkCode() {
|
|
|
+ try {
|
|
|
+ // 获取验证码
|
|
|
+ CaptchaUtil.outputCaptcha(request, response, LOGIN_CAPTCHA);
|
|
|
+ } catch (ServletException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获得密码输错次数
|
|
|
+ *
|
|
|
+ * @param username 用户名
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/getPwdErrorCount", method = RequestMethod.GET)
|
|
|
+ public ModelMap getPwdErrorCount(String username) {
|
|
|
+ if (StringUtils.isEmpty(username)) {
|
|
|
+ return error("用户名不能为空");
|
|
|
+ }
|
|
|
+ return success(userService.getPwdErrorCount(username));
|
|
|
+ }
|
|
|
}
|