package com.uas.sso.controller; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.uas.sso.SSOConfig; import com.uas.sso.SSOHelper; 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.UserAccount; 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.web.waf.request.WafRequestWrapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ui.ModelMap; 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 java.util.*; /** * 登录controller * * @author wangmh * @date 2018/1/5 */ @RequestMapping("/sso/login") @RestController public class LoginController extends BaseController { @Autowired private AppService appService; @Autowired private UserService userService; @Autowired private UserAccountService userAccountService; @RequestMapping(method = RequestMethod.POST) @ResponseBody public ModelMap login() { // 获取登录信息 WafRequestWrapper wr = new WafRequestWrapper(request); String appId = wr.getParameter("appId"); String spaceUU = wr.getParameter("spaceUU"); String username = StringUtils.trimAllWhitespace(wr.getParameter("username")); String password = wr.getParameter("password"); String returnUrl = wr.getParameter("returnUrl"); String baseUrl = wr.getParameter("baseUrl"); // 校验空参数 if (StringUtils.isEmpty(username)) { return error("用户名不能为空"); } if (StringUtils.isEmpty(password)) { return error("密码不能为空"); } // 设置baseUrl if (!StringUtils.isEmpty(baseUrl)) { request.getSession().setAttribute("baseUrl", baseUrl); } // 校验appId,appId为空的话默认为sso appId = StringUtils.isEmpty(appId) ? "sso" : appId; App app = appService.findOne(appId); if (app == null) { return error("应用id不存在"); } // 登录 App controlApp = StringUtils.isEmpty(app.getUserControl()) ? app : appService.findOne(app.getUserControl()); boolean personalEnable = Const.YES == controlApp.getPersonalEnable(); if (StringUtils.isEmpty(spaceUU)) { /*企业uu号为空,让用户选择企业*/ // 找到用户账号信息 List userAccounts = getUserAccountByUserName(controlApp.getUid(), username); // 应用不允许个人账号,并且账号未绑定企业 if (!personalEnable && CollectionUtils.isEmpty(userAccounts)) { return error("用户名或密码错误"); } // 应用允许个人账号,并且账号未绑定企业,或者只绑定了一个企业,直接登录 if (userAccounts.size() == 1) { return loginByUser(userAccounts.get(0), password, returnUrl); } // 由于老账户存在多个账号绑定一个邮箱的情况,把密码不符合的企业去除 Iterator 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(); } } // 返回企业id和名称 return success(getSpaceSelect(userAccounts, personalEnable)); } else if (spaceUU.equals(Const.SPACEUU_PERSONAL)) { // 使用个人账号登录 UserAccount userAccount = getUserAccountByUserName(controlApp.getUid(), username, null); return loginByUser(userAccount, password, returnUrl); } else { // 带企业登录 UserAccount userAccount = getUserAccountByUserName(controlApp.getUid(), username, spaceUU); return loginByUser(userAccount, password, returnUrl); } } private List getUserAccountByUserName(String appId, String username) { String type = AccountTypeUtils.getAccountType(username); if (AccountTypeUtils.MOBILE.equals(type)) { // 手机号登录 return userAccountService.findByMobile(appId, username); } if (AccountTypeUtils.EMAIL.equals(type)) { // 邮箱登录 return userAccountService.findByEmail(appId, username); } if (AccountTypeUtils.UU_NUMBER.equals(type)) { // uu号登录 return userAccountService.findOneByUserUU(appId, Long.valueOf(username)); } // 其余情况 return null; } private UserAccount getUserAccountByUserName(String appId, String username, String spaceUU) { String type = AccountTypeUtils.getAccountType(username); if (AccountTypeUtils.MOBILE.equals(type)) { // 手机号登录 return userAccountService.findOneByMobile(appId, username, spaceUU); } if (AccountTypeUtils.EMAIL.equals(type)) { // 邮箱登录 return userAccountService.findOneByEmail(appId, username, spaceUU); } if (AccountTypeUtils.UU_NUMBER.equals(type)) { // uu号登录 return userAccountService.findOneByUserUU(appId, Long.valueOf(username), spaceUU); } // 其余情况 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("您输入的账号或密码有误"); } // 登录 /* * 设置登录 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); } } private ModelMap addOtherAppRequestData(UserAccount userAccount, ModelMap data, Object loginUrl, boolean isLoginAll) { // 需要通知的应用数量 int count = 0; List apps = appService.findAll(); List loginUrls = new ArrayList<>(); boolean hasLoginUrl = false; if (isLoginAll) { for (App app : apps) { if (StringUtils.isEmpty(app.getLoginUrl())) { continue; } if (app.getLoginUrl().equals(loginUrl)) { 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); // 添加传递数据 JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(userAccount)); Integer maxage = (Integer) request.getAttribute(SSOConfig.SSO_COOKIE_MAXAGE); jsonObject.put("maxage", maxage); data.put("data", jsonObject); return data; } /** * 获取选择企业信息(id:企业uu号,name:名称) * * @param userAccounts 用户账户信息 * @param personalEnable 该应用是否允许个人账户 * @return */ private ModelMap getSpaceSelect(List userAccounts, boolean personalEnable) { List> spaces = new ArrayList>(); Map space = null; // 设置带企业账号 for (UserAccount userAccount : userAccounts) { space = new HashMap(2); space.put("id", userAccount.getSpaceUU()); space.put("name", userAccount.getSpaceName()); } // 设置个人账号 if (personalEnable) { space = new HashMap(2); space.put("id", Const.SPACEUU_PERSONAL); space.put("name", String.format("%s(个人)", userAccounts.get(0).getVipName())); } return new ModelMap("spaces", spaces); } }