|
|
@@ -0,0 +1,250 @@
|
|
|
+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<UserAccount> userAccounts = getUserAccountByUserName(controlApp.getUid(), username);
|
|
|
+
|
|
|
+ // 应用不允许个人账号,并且账号未绑定企业
|
|
|
+ if (!personalEnable && 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();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 返回企业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<UserAccount> 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<App> apps = appService.findAll();
|
|
|
+ List<String> 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<UserAccount> userAccounts, boolean personalEnable) {
|
|
|
+ List<Map<String, Object>> spaces = new ArrayList<Map<String, Object>>();
|
|
|
+ Map<String, Object> space = null;
|
|
|
+ // 设置带企业账号
|
|
|
+ for (UserAccount userAccount : userAccounts) {
|
|
|
+ space = new HashMap<String, Object>(2);
|
|
|
+ space.put("id", userAccount.getSpaceUU());
|
|
|
+ space.put("name", userAccount.getSpaceName());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置个人账号
|
|
|
+ if (personalEnable) {
|
|
|
+ space = new HashMap<String, Object>(2);
|
|
|
+ space.put("id", Const.SPACEUU_PERSONAL);
|
|
|
+ space.put("name", String.format("%s(个人)", userAccounts.get(0).getVipName()));
|
|
|
+ }
|
|
|
+ return new ModelMap("spaces", spaces);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|