PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/src/com/jeecms/core/action/front/LoginAct.java

https://gitlab.com/mdly/ncly-searchs
Java | 199 lines | 142 code | 14 blank | 43 comment | 30 complexity | 38e5203758a10b229f8adc93eb464165 MD5 | raw file
  1. package com.jeecms.core.action.front;
  2. import static com.jeecms.core.manager.AuthenticationMng.AUTH_KEY;
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletResponse;
  5. import ch.qos.logback.core.joran.spi.ConsoleTarget;
  6. import org.apache.commons.lang.StringUtils;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.stereotype.Controller;
  9. import org.springframework.ui.ModelMap;
  10. import org.springframework.web.bind.annotation.RequestMapping;
  11. import org.springframework.web.bind.annotation.RequestMethod;
  12. import com.jeecms.common.security.BadCredentialsException;
  13. import com.jeecms.common.security.UsernameNotFoundException;
  14. import com.jeecms.common.web.RequestUtils;
  15. import com.jeecms.common.web.session.SessionProvider;
  16. import com.jeecms.core.entity.Authentication;
  17. import com.jeecms.core.manager.AuthenticationMng;
  18. import com.jeecms.core.web.WebCoreErrors;
  19. /**
  20. * 统一认证中心Action
  21. *
  22. * 统一认证中心由两个方面组成。
  23. * <ul>
  24. * <li>
  25. * 用户信息来源。 可以有多种来源,最合适的来源是LDAP,也可以是数据库。本认证中心为实现更实用于互联网的、更轻量级的单点登录,使用数据库作为用户信息来源。
  26. * 只要在同一数据库实例下,即可访问到用户信息。各系统可以自行实现注册、修改密码、禁用等功能。如果是用一体系下的应用,这些功能都提供了统一接口。
  27. * <li>
  28. * 用户认证信息。用户登录成功后,需要保存登录信息,最合适的保存技术是memcached,也可以是其他集群缓存或数据库。本认证中心使用数据库保存登录信息。
  29. * 只要在同一数据库实例下,即可访问。各系统可以自行实现退出登录。
  30. * </ul>
  31. */
  32. @Controller
  33. public class LoginAct {
  34. public static final String PROCESS_URL = "processUrl";
  35. public static final String RETURN_URL = "returnUrl";
  36. public static final String MESSAGE = "message";
  37. public static final String LOGIN_INPUT = "/WEB-INF/t/jeecore/login.html";
  38. public static final String LOGIN_SUCCESS = "/WEB-INF/t/jeecore/login_success.html";
  39. /**
  40. * 统一登录入口
  41. *
  42. * 入口有三种作用
  43. * <ul>
  44. * <li>统一登录中心测试用。直接输入登录地址,登录成功后返回登录成功界面。如果processUrl为空,则认为使用该功能。</li>
  45. * <li>统一登录。其他系统使用该入口统一登录。使用此功能proseccUrl不能为空。</li>
  46. * <li>单点登录。多系统通过该入口实现单点登录。如果session中AUTH_KEY存在,则直接重定向至proseccUrl。</li>
  47. * </ul>
  48. *
  49. * @param processUrl
  50. * 登录成功后的处理地址。登录成功后即重定向到该页面,并将returnUrl、auth_key作为参数。
  51. * @param returnUrl
  52. * 登录成功,并处理后,返回到该地址。
  53. * @param message
  54. * 登录是提示的信息,比如:“您需要登录后才能继续刚才的操作”,该信息必须用UTF-8编码进行URLEncode。
  55. * @param request
  56. * @param model
  57. * @return 重定向至processUrl,如prosessUrl不存在,则返回登录成功界面。
  58. */
  59. @RequestMapping(value = "/login.jspx", method = RequestMethod.GET)
  60. public String input(HttpServletRequest request, ModelMap model) {
  61. String processUrl = RequestUtils.getQueryParam(request, PROCESS_URL);
  62. String returnUrl = RequestUtils.getQueryParam(request, RETURN_URL);
  63. String message = RequestUtils.getQueryParam(request, MESSAGE);
  64. String authId = (String) session.getAttribute(request, AUTH_KEY);
  65. if (authId != null) {
  66. // 存在认证ID
  67. Authentication auth = authMng.retrieve(authId);
  68. // 存在认证信息,且未过期
  69. if (auth != null) {
  70. String view = getView(processUrl, returnUrl, auth.getId());
  71. if (view != null) {
  72. return view;
  73. } else {
  74. model.addAttribute("auth", auth);
  75. return LOGIN_SUCCESS;
  76. }
  77. }
  78. }
  79. if (!StringUtils.isBlank(processUrl)) {
  80. model.addAttribute(PROCESS_URL, processUrl);
  81. }
  82. if (!StringUtils.isBlank(returnUrl)) {
  83. model.addAttribute(RETURN_URL, returnUrl);
  84. }
  85. if (!StringUtils.isBlank(message)) {
  86. model.addAttribute(MESSAGE, message);
  87. }
  88. return LOGIN_INPUT;
  89. }
  90. @RequestMapping(value = "/login.jspx", method = RequestMethod.POST)
  91. public String submit(String username, String password, String processUrl,
  92. String returnUrl, String message, HttpServletRequest request,
  93. HttpServletResponse response, ModelMap model) {
  94. WebCoreErrors errors = validateSubmit(username, password, request);
  95. if (!errors.hasErrors()) {
  96. try {
  97. Authentication auth = authMng.login(username, password,
  98. RequestUtils.getIpAddr(request), request, response,
  99. session);
  100. String view = getView(processUrl, returnUrl, auth.getId());
  101. if (view != null) {
  102. return view;
  103. } else {
  104. model.addAttribute("auth", auth);
  105. return LOGIN_SUCCESS;
  106. }
  107. } catch (UsernameNotFoundException e) {
  108. errors.addErrorString(e.getMessage());
  109. } catch (BadCredentialsException e) {
  110. errors.addErrorString(e.getMessage());
  111. }
  112. }
  113. errors.toModel(model);
  114. if (!StringUtils.isBlank(processUrl)) {
  115. model.addAttribute(PROCESS_URL, processUrl);
  116. }
  117. if (!StringUtils.isBlank(returnUrl)) {
  118. model.addAttribute(RETURN_URL, returnUrl);
  119. }
  120. if (!StringUtils.isBlank(message)) {
  121. model.addAttribute(MESSAGE, message);
  122. }
  123. return LOGIN_INPUT;
  124. }
  125. @RequestMapping(value = "/logout.jspx")
  126. public String logout(HttpServletRequest request,
  127. HttpServletResponse response) {
  128. String authId = (String) session.getAttribute(request, AUTH_KEY);
  129. if (authId != null) {
  130. authMng.deleteById(authId);
  131. session.logout(request, response);
  132. }
  133. String processUrl = RequestUtils.getQueryParam(request, PROCESS_URL);
  134. String returnUrl = RequestUtils.getQueryParam(request, RETURN_URL);
  135. String view = getView(processUrl, returnUrl, authId);
  136. if (view != null) {
  137. return view;
  138. } else {
  139. return "redirect:login.jspx";
  140. }
  141. }
  142. /**
  143. * 获得地址
  144. *
  145. * @param processUrl
  146. * @param returnUrl
  147. * @param authId
  148. * @return
  149. */
  150. private String getView(String processUrl, String returnUrl, String authId) {
  151. if (!StringUtils.isBlank(processUrl)) {
  152. StringBuilder sb = new StringBuilder("redirect:");
  153. sb.append(processUrl).append("?").append(AUTH_KEY).append("=")
  154. .append(authId);
  155. if (!StringUtils.isBlank(returnUrl)) {
  156. sb.append("&").append(RETURN_URL).append("=").append(returnUrl);
  157. }
  158. return sb.toString();
  159. } else if (!StringUtils.isBlank(returnUrl)) {
  160. StringBuilder sb = new StringBuilder("redirect:");
  161. sb.append(returnUrl);
  162. if (!StringUtils.isBlank(authId)) {
  163. sb.append("?").append(AUTH_KEY).append("=").append(authId);
  164. }
  165. return sb.toString();
  166. } else {
  167. return null;
  168. }
  169. }
  170. private WebCoreErrors validateSubmit(String username, String password,
  171. HttpServletRequest request) {
  172. WebCoreErrors errors = WebCoreErrors.create(request);
  173. if (errors.ifOutOfLength(username, "username", 3, 100)) {
  174. return errors;
  175. }
  176. if (errors.ifOutOfLength(password, "password", 3, 32)) {
  177. return errors;
  178. }
  179. return errors;
  180. }
  181. @Autowired
  182. private AuthenticationMng authMng;
  183. @Autowired
  184. private SessionProvider session;
  185. }