LoginController.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. /**
  2. * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
  3. */
  4. package com.jeeplus.modules.sys.web;
  5. import java.io.IOException;
  6. import java.util.HashMap;
  7. import java.util.Map;
  8. import javax.servlet.http.Cookie;
  9. import javax.servlet.http.HttpServletRequest;
  10. import javax.servlet.http.HttpServletResponse;
  11. import com.jeeplus.common.utils.*;
  12. import com.jeeplus.modules.act.entity.Act;
  13. import com.jeeplus.modules.act.service.ActTaskService;
  14. import io.swagger.annotations.Api;
  15. import io.swagger.annotations.ApiImplicitParam;
  16. import io.swagger.annotations.ApiImplicitParams;
  17. import io.swagger.annotations.ApiOperation;
  18. import org.apache.shiro.authz.UnauthorizedException;
  19. import org.apache.shiro.authz.annotation.RequiresPermissions;
  20. import org.apache.shiro.web.util.SavedRequest;
  21. import org.apache.shiro.web.util.WebUtils;
  22. import org.springframework.beans.factory.annotation.Autowired;
  23. import org.springframework.stereotype.Controller;
  24. import org.springframework.ui.Model;
  25. import org.springframework.web.bind.annotation.PathVariable;
  26. import org.springframework.web.bind.annotation.RequestMapping;
  27. import org.springframework.web.bind.annotation.RequestMethod;
  28. import com.google.common.collect.Maps;
  29. import com.jeeplus.common.config.Global;
  30. import com.jeeplus.common.json.AjaxJson;
  31. import com.jeeplus.core.persistence.Page;
  32. import com.jeeplus.core.security.shiro.session.SessionDAO;
  33. import com.jeeplus.core.servlet.ValidateCodeServlet;
  34. import com.jeeplus.core.web.BaseController;
  35. import com.jeeplus.modules.iim.entity.MailBox;
  36. import com.jeeplus.modules.iim.entity.MailPage;
  37. import com.jeeplus.modules.iim.service.MailBoxService;
  38. import com.jeeplus.modules.oa.entity.OaNotify;
  39. import com.jeeplus.modules.oa.service.OaNotifyService;
  40. import com.jeeplus.modules.sys.security.FormAuthenticationFilter;
  41. import com.jeeplus.modules.sys.security.SystemAuthorizingRealm.Principal;
  42. import com.jeeplus.modules.sys.utils.UserUtils;
  43. import org.springframework.web.bind.annotation.ResponseBody;
  44. /**
  45. * 登录Controller
  46. * @author jeeplus
  47. * @version 2016-5-31
  48. */
  49. @Api(value = "LoginController", description = "登录控制器")
  50. @Controller
  51. public class LoginController extends BaseController{
  52. @Autowired
  53. private SessionDAO sessionDAO;
  54. @Autowired
  55. private OaNotifyService oaNotifyService;
  56. @Autowired
  57. private MailBoxService mailBoxService;
  58. @Autowired
  59. private ActTaskService actTaskService;
  60. /**
  61. * 管理登录
  62. * @throws IOException
  63. */
  64. @ApiOperation(notes = "login", httpMethod = "POST", value = "用户登录")
  65. @ApiImplicitParams({@ApiImplicitParam(name = "username", value = "用户名", required = true, paramType = "query",dataType = "string"),
  66. @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query",dataType = "string"),
  67. @ApiImplicitParam(name="mobileLogin",value = "接口标志",required = true, paramType = "query",dataType = "string")})
  68. @RequestMapping(value = "${adminPath}/login")
  69. public String login(HttpServletRequest request, HttpServletResponse response) throws IOException {
  70. Principal principal = UserUtils.getPrincipal();
  71. if (logger.isDebugEnabled()){
  72. logger.debug("login, active session size: {}", sessionDAO.getActiveSessions(false).size());
  73. }
  74. // 如果已登录,再次访问主页,则退出原账号。
  75. if (Global.TRUE.equals(Global.getConfig("notAllowRefreshIndex"))){
  76. CookieUtils.setCookie(response, "LOGINED", "false");
  77. }
  78. // 如果已经登录,则跳转到管理首页
  79. if(principal != null && !principal.isMobileLogin()){
  80. return "redirect:" + adminPath;
  81. }
  82. SavedRequest savedRequest = WebUtils.getSavedRequest(request);//获取跳转到login之前的URL
  83. // 如果是手机没有登录跳转到到login,则返回JSON字符串
  84. if(savedRequest != null){
  85. String queryStr = savedRequest.getQueryString();
  86. if( queryStr!=null &&( queryStr.contains("__ajax") || queryStr.contains("mobileLogin"))){
  87. AjaxJson j = new AjaxJson();
  88. j.setSuccess(false);
  89. j.setErrorCode("0");
  90. j.setMsg("没有登录!");
  91. return renderString(response, j);
  92. }
  93. }
  94. return "modules/sys/login/sysLogin";
  95. }
  96. /**
  97. * 登录失败,真正登录的POST请求由Filter完成
  98. */
  99. @RequestMapping(value = "${adminPath}/login", method = RequestMethod.POST)
  100. public String loginFail(HttpServletRequest request, HttpServletResponse response, Model model) {
  101. Principal principal = UserUtils.getPrincipal();
  102. // 如果已经登录,则跳转到管理首页
  103. if(principal != null){
  104. return "redirect:" + adminPath;
  105. }
  106. String username = WebUtils.getCleanParam(request, FormAuthenticationFilter.DEFAULT_USERNAME_PARAM);
  107. boolean rememberMe = WebUtils.isTrue(request, FormAuthenticationFilter.DEFAULT_REMEMBER_ME_PARAM);
  108. boolean mobile = WebUtils.isTrue(request, FormAuthenticationFilter.DEFAULT_MOBILE_PARAM);
  109. String exception = (String)request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
  110. String message = (String)request.getAttribute(FormAuthenticationFilter.DEFAULT_MESSAGE_PARAM);
  111. if (StringUtils.isBlank(message) || StringUtils.equals(message, "null")){
  112. message = "用户或密码错误, 请重试.";
  113. }
  114. model.addAttribute(FormAuthenticationFilter.DEFAULT_USERNAME_PARAM, username);
  115. model.addAttribute(FormAuthenticationFilter.DEFAULT_REMEMBER_ME_PARAM, rememberMe);
  116. model.addAttribute(FormAuthenticationFilter.DEFAULT_MOBILE_PARAM, mobile);
  117. model.addAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME, exception);
  118. model.addAttribute(FormAuthenticationFilter.DEFAULT_MESSAGE_PARAM, message);
  119. if (logger.isDebugEnabled()){
  120. logger.debug("login fail, active session size: {}, message: {}, exception: {}",
  121. sessionDAO.getActiveSessions(false).size(), message, exception);
  122. }
  123. // 非授权异常,登录失败,验证码加1。
  124. if (!UnauthorizedException.class.getName().equals(exception)){
  125. model.addAttribute("isValidateCodeLogin", isValidateCodeLogin(username, true, false));
  126. }
  127. // 验证失败清空验证码
  128. request.getSession().setAttribute(ValidateCodeServlet.VALIDATE_CODE, IdGen.uuid());
  129. // 如果是手机登录,则返回JSON字符串
  130. if (mobile){
  131. AjaxJson j = new AjaxJson();
  132. j.setSuccess(false);
  133. j.setMsg(message);
  134. j.put("username", username);
  135. j.put("name","");
  136. j.put("mobileLogin", mobile);
  137. j.put("JSESSIONID", "");
  138. return renderString(response, j.getJsonStr());
  139. }
  140. return "modules/sys/login/sysLogin";
  141. }
  142. /**
  143. * 管理登录
  144. * @throws IOException
  145. */
  146. @RequestMapping(value = "${adminPath}/logout", method = RequestMethod.GET)
  147. public String logout(HttpServletRequest request, HttpServletResponse response, Model model) throws IOException {
  148. Principal principal = UserUtils.getPrincipal();
  149. // 如果已经登录,则跳转到管理首页
  150. if(principal != null){
  151. UserUtils.getSubject().logout();
  152. }
  153. // 如果是手机客户端退出跳转到login,则返回JSON字符串
  154. String ajax = request.getParameter("__ajax");
  155. if( ajax!=null){
  156. model.addAttribute("success", "1");
  157. model.addAttribute("msg", "退出成功");
  158. return renderString(response, model);
  159. }
  160. return "redirect:" + adminPath+"/login";
  161. }
  162. /**
  163. * 登录成功,进入管理首页
  164. */
  165. @RequiresPermissions("user")
  166. @RequestMapping(value = "${adminPath}")
  167. public String index(HttpServletRequest request, HttpServletResponse response) {
  168. Principal principal = UserUtils.getPrincipal();
  169. // 登录成功后,验证码计算器清零
  170. isValidateCodeLogin(principal.getLoginName(), false, true);
  171. if (logger.isDebugEnabled()){
  172. logger.debug("show index, active session size: {}", sessionDAO.getActiveSessions(false).size());
  173. }
  174. // 如果已登录,再次访问主页,则退出原账号。
  175. if (Global.TRUE.equals(Global.getConfig("notAllowRefreshIndex"))){
  176. String logined = CookieUtils.getCookie(request, "LOGINED");
  177. if (StringUtils.isBlank(logined) || "false".equals(logined)){
  178. CookieUtils.setCookie(response, "LOGINED", "true");
  179. }else if (StringUtils.equals(logined, "true")){
  180. UserUtils.getSubject().logout();
  181. return "redirect:" + adminPath + "/login";
  182. }
  183. }
  184. // 如果是手机登录,则返回JSON字符串
  185. if (principal.isMobileLogin()){
  186. if (request.getParameter("login") != null){
  187. return renderString(response, principal);
  188. }
  189. if (request.getParameter("index") != null){
  190. return "modules/sys/login/sysIndex";
  191. }
  192. return "redirect:" + adminPath + "/login";
  193. }
  194. OaNotify oaNotify = new OaNotify();
  195. oaNotify.setSelf(true);
  196. oaNotify.setReadFlag("0");
  197. Page<OaNotify> page = oaNotifyService.find(new Page<OaNotify>(request, response), oaNotify);
  198. request.setAttribute("page", page);
  199. request.setAttribute("count", page.getList().size());//未读通知条数
  200. //
  201. MailBox mailBox = new MailBox();
  202. mailBox.setReceiver(UserUtils.getUser());
  203. mailBox.setReadstatus("0");//筛选未读
  204. request.setAttribute("noReadCount", mailBoxService.getCount(mailBox));
  205. Page<MailBox> mailPage = mailBoxService.findPage(new MailPage<MailBox>(request, response), mailBox);
  206. request.setAttribute("mailPage", mailPage);
  207. if(UserUtils.getMenuList().size() == 0){
  208. return "modules/sys/login/noAuth";
  209. }else{
  210. // 默认风格
  211. String indexStyle ;
  212. if(MobileUtils.checkAgentIsMobile(request.getHeader("User-Agent"))){//如果是移动,默认使用左侧菜单,显示效果较好
  213. indexStyle = "ani";
  214. }else{//如果是pc端,默认使用jeeplus.properties中的配置项,jp横向菜单,ani左侧菜单
  215. indexStyle = Global.getDefaultTheme();
  216. }
  217. Cookie[] cookies = request.getCookies();
  218. for (Cookie cookie : cookies) {
  219. if (cookie == null || StringUtils.isEmpty(cookie.getName())) {
  220. continue;
  221. }
  222. if (cookie.getName().equalsIgnoreCase("style")) {
  223. indexStyle = cookie.getValue();
  224. }
  225. }
  226. // 要添加自己的风格,复制下面三行即可
  227. if (StringUtils.isNotEmpty(indexStyle)
  228. && indexStyle.equalsIgnoreCase("jp")) {
  229. return "modules/sys/login/sysIndex-jp";
  230. }
  231. return "modules/sys/login/sysIndex";
  232. }
  233. }
  234. /**
  235. * 切换风格
  236. */
  237. @ResponseBody
  238. @RequestMapping(value = "${adminPath}/style/{style}")
  239. public String getStyleInCookie(@PathVariable String style, HttpServletRequest request, HttpServletResponse response){
  240. if (StringUtils.isNotBlank(style)){
  241. CookieUtils.setCookie(response, "style", style);
  242. }else{
  243. style = CookieUtils.getCookie(request, "style");
  244. }
  245. return style;
  246. }
  247. /**
  248. * 获取主题颜色方案
  249. */
  250. @ResponseBody
  251. @RequestMapping(value = "${adminPath}/theme/{theme}")
  252. public String getThemeInCookie(@PathVariable String theme, HttpServletRequest request, HttpServletResponse response){
  253. if (StringUtils.isNotBlank(theme)){
  254. if(theme.contains("_")){
  255. String style = theme.split("_")[0];
  256. theme = theme.split("_")[1];
  257. if(style.equals("white")){
  258. CookieUtils.setCookie(response, "white", "theme-whbl");
  259. }else{
  260. CookieUtils.setCookie(response, "white", "");
  261. }
  262. CookieUtils.setCookie(response, "theme", theme);
  263. }else{
  264. CookieUtils.setCookie(response, "theme", theme);
  265. }
  266. }else{
  267. theme = CookieUtils.getCookie(request, "theme");
  268. }
  269. return theme;
  270. }
  271. /**
  272. * 是否启用tab
  273. */
  274. @RequestMapping(value = "${adminPath}/tab/{tab}")
  275. public String getTabInCookie(@PathVariable String tab, HttpServletRequest request, HttpServletResponse response){
  276. if (StringUtils.isNotBlank(tab)){
  277. CookieUtils.setCookie(response, "tab", tab);
  278. }else{
  279. tab = CookieUtils.getCookie(request, "tab");
  280. }
  281. return "redirect:"+request.getParameter("url");
  282. }
  283. /**
  284. * 是否是验证码登录
  285. * @param useruame 用户名
  286. * @param isFail 计数加1
  287. * @param clean 计数清零
  288. * @return
  289. */
  290. @SuppressWarnings("unchecked")
  291. public static boolean isValidateCodeLogin(String useruame, boolean isFail, boolean clean){
  292. Map<String, Integer> loginFailMap = (Map<String, Integer>)CacheUtils.get("loginFailMap");
  293. if (loginFailMap==null){
  294. loginFailMap = Maps.newHashMap();
  295. CacheUtils.put("loginFailMap", loginFailMap);
  296. }
  297. Integer loginFailNum = loginFailMap.get(useruame);
  298. if (loginFailNum==null){
  299. loginFailNum = 0;
  300. }
  301. if (isFail){
  302. loginFailNum++;
  303. loginFailMap.put(useruame, loginFailNum);
  304. }
  305. if (clean){
  306. loginFailMap.remove(useruame);
  307. }
  308. return loginFailNum >= 3;
  309. }
  310. /**
  311. * 首页
  312. * @throws IOException
  313. */
  314. @RequestMapping(value = "${adminPath}/home")
  315. public String home(HttpServletRequest request, HttpServletResponse response, Model model) throws IOException {
  316. Act act = new Act();
  317. Page<HashMap<String,String>> page = actTaskService.todoList(new Page<HashMap<String,String>>(request, response),act);
  318. model.addAttribute("actlist",page.getList());
  319. model.addAttribute("actCount",page.getCount());
  320. return "modules/sys/login/sysHome";
  321. }
  322. }