package com.landtool.lanbase.modules.sys.controller;
|
|
import java.awt.image.BufferedImage;
|
import java.io.IOException;
|
import java.net.URLEncoder;
|
import java.util.Map;
|
import java.util.concurrent.ConcurrentHashMap;
|
|
import javax.imageio.ImageIO;
|
import javax.servlet.ServletException;
|
import javax.servlet.ServletOutputStream;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
|
import org.apache.commons.io.IOUtils;
|
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.session.Session;
|
import org.apache.shiro.subject.Subject;
|
import org.apache.shiro.util.StringUtils;
|
import org.apache.shiro.web.util.SavedRequest;
|
import org.apache.shiro.web.util.WebUtils;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.scheduling.annotation.Scheduled;
|
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 com.alibaba.druid.support.json.JSONUtils;
|
import com.alibaba.fastjson.JSONObject;
|
import com.google.code.kaptcha.Constants;
|
import com.google.code.kaptcha.Producer;
|
import com.landtool.lanbase.common.Constant;
|
import com.landtool.lanbase.common.annotation.LogLogininfo;
|
import com.landtool.lanbase.common.exception.LanbaseException;
|
import com.landtool.lanbase.common.shiro.ShiroToken;
|
import com.landtool.lanbase.common.utils.CoderUtils;
|
import com.landtool.lanbase.common.utils.HttpUtils;
|
import com.landtool.lanbase.common.utils.RedisUtils;
|
import com.landtool.lanbase.common.utils.Result;
|
import com.landtool.lanbase.common.utils.ShiroUtils;
|
import com.landtool.lanbase.config.SysTemPropertyConfig;
|
import com.landtool.lanbase.modules.org.entity.OrgUser;
|
import com.landtool.lanbase.modules.org.service.OrgUserService;
|
import com.landtool.lanbase.modules.sys.redis.OnlineUserRedis;
|
import com.landtool.lanbase.modules.sys.service.SysUserTokenService;
|
|
import springfox.documentation.annotations.ApiIgnore;
|
|
/**
|
* @author lanbase
|
* @Description: TODO(登录相关)
|
* @date 2017-6-23 15:07
|
*/
|
@RestController
|
@ApiIgnore()
|
public class SysLoginController extends AbstractController {
|
|
private Logger logger = LoggerFactory.getLogger(getClass());
|
|
@Autowired
|
private Producer producer;
|
@Autowired
|
private OrgUserService orgUserService;
|
@Autowired
|
private SysUserTokenService sysUserTokenService;
|
@Autowired
|
private SysTemPropertyConfig sysConfig;
|
|
@Autowired
|
private OnlineUserRedis onlineUserRedis;
|
@Autowired
|
private RedisUtils redisUtils;
|
/**
|
* 在线人数map
|
*/
|
private static ConcurrentHashMap<String,Object> onlineuser=new ConcurrentHashMap<String,Object>();
|
|
|
/**
|
* 首页
|
*
|
* @param request
|
* @param response
|
* @throws IOException
|
*/
|
@RequestMapping(value = "/", method = RequestMethod.GET)
|
public void hutaiadmin(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
response.sendRedirect("/res/ZiYuanZhongXin/index?Menu=ZYZX&menuId=07");
|
// cannot call sendRedirect() after the response has been commited
|
// 1、resopnse 重定向后没有return
|
// 2、重定向后还有重定向,重复的重定向
|
return;
|
}
|
|
@RequestMapping("/captcha.jpg")
|
public void captcha(HttpServletResponse response) throws ServletException, IOException {
|
response.setHeader("Cache-Control", "no-store, no-cache");
|
response.setContentType("image/jpeg");
|
|
// 生成文字验证码
|
String text = producer.createText();
|
// 生成图片验证码
|
BufferedImage image = producer.createImage(text);
|
// 保存到shiro session
|
ShiroUtils.setSessionAttribute(Constants.KAPTCHA_SESSION_KEY, text);
|
|
ServletOutputStream out = response.getOutputStream();
|
ImageIO.write(image, "jpg", out);
|
IOUtils.closeQuietly(out);
|
}
|
|
/**
|
* 获取登录错误次数
|
*/
|
@RequestMapping(value = "/sys/getLoginErrorTimes", method = RequestMethod.GET)
|
public Result getLoginErrorTimes() {
|
Object errorTimes = ShiroUtils.getSessionAttribute(Constant.LOGIN_ERROR_TIMES);
|
return Result.ok().put("errorTimes", errorTimes);
|
}
|
|
/**
|
* 登录
|
*/
|
@LogLogininfo("登录")
|
@RequestMapping(value = "/sys/login", method = RequestMethod.POST)
|
public Result login(String username, String password, String captcha) throws IOException {
|
Object _login_errors = ShiroUtils.getSessionAttribute(Constant.LOGIN_ERROR_TIMES);
|
if (_login_errors == null) {
|
_login_errors = 0;
|
}
|
long errorTimes = Long.valueOf(_login_errors.toString());
|
|
// 用户信息
|
OrgUser user = orgUserService.queryByUserName(username);
|
|
// 账号不存在
|
if (user == null) {
|
ShiroUtils.setSessionAttribute(Constant.LOGIN_ERROR_TIMES, ++errorTimes);
|
return Result.error("账号不存在").put("errorTimes", errorTimes);
|
}
|
|
// 密码错误
|
try {
|
if (!user.getPassword().equals(CoderUtils.lantuEncryptMD5(password))) {
|
ShiroUtils.setSessionAttribute(Constant.LOGIN_ERROR_TIMES, ++errorTimes);
|
return Result.error("密码不正确").put("errorTimes", errorTimes);
|
}
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
}
|
|
// 验证码
|
if (errorTimes >= 3) {
|
String kaptcha = getKaptcha(Constants.KAPTCHA_SESSION_KEY);
|
if (!captcha.equalsIgnoreCase(kaptcha)) {
|
ShiroUtils.setSessionAttribute(Constant.LOGIN_ERROR_TIMES, ++errorTimes);
|
return Result.error("验证码不正确").put("errorTimes", errorTimes);
|
}
|
}
|
|
// 账号锁定
|
if (Constant.UserStatus.DISABLE.getValue() == user.getUserstatus()) {
|
ShiroUtils.setSessionAttribute(Constant.LOGIN_ERROR_TIMES, ++errorTimes);
|
return Result.error("账号已被锁定,请联系管理员").put("errorTimes", errorTimes);
|
}
|
|
// 生成token,并保存到数据库
|
Map<String, Object> result = sysUserTokenService.createToken(user.getUserid());
|
Result r = Result.ok().put(result);
|
return r;
|
}
|
|
private String getLoginNamefromXml(HttpServletRequest request) throws Exception {
|
String username = "";
|
|
Subject subject = SecurityUtils.getSubject();
|
Session session = subject.getSession(true);
|
username = session.getAttribute("shirousername") == null ? ""
|
: session.getAttribute("shirousername").toString();
|
logger.debug("4----shirousername:" + session.getAttribute("shirousername") + (session.getId()));
|
if (org.springframework.util.StringUtils.isEmpty(username)) {
|
String CasHost = sysConfig.getCasHost();// https://cas.nmsmp.com/cas/
|
String loginUrl = sysConfig.getLoginUrl(); // http://127.0.0.1:8082/login
|
|
String ticket = request.getParameter("ticket");
|
|
if (!org.springframework.util.StringUtils.isEmpty(ticket)) {
|
String server = getOldQueryString(request);
|
String url = CasHost.replace("https", "http");
|
String validateurl = url + "serviceValidate?ticket=" + ticket + "&service=" + loginUrl + "?oldurl="
|
+ URLEncoder.encode(server);
|
;
|
|
logger.debug("2----ServiceValidate:" + validateurl);
|
|
String casxml;
|
casxml = HttpUtils.get(validateurl);
|
logger.debug(casxml);
|
Integer index = casxml.indexOf("<cas:user>");
|
Integer end = casxml.indexOf("</cas:user>");
|
|
if (index > 0) {
|
username = casxml.substring(index + 10, end);
|
}
|
}
|
}
|
return username;
|
}
|
|
@LogLogininfo("登录")
|
@RequestMapping(value = "/index", method = RequestMethod.GET)
|
@ResponseBody
|
public void index(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
String username = request.getRemoteUser();
|
response.setCharacterEncoding("utf-8");
|
response.setContentType("text/plain");
|
response.getWriter().write(username + "登陆成功!");
|
}
|
|
/**
|
* oa门户反验证 获取地址上的validatename,调用反验证接口获取结果,为true,则允许登录
|
*/
|
|
public JSONObject portallogin(HttpServletRequest request) {
|
String result = "";
|
String querystring = request.getQueryString();
|
String username = "";
|
if (querystring != null) {
|
String par[] = querystring.split("&");
|
for (int i = 0; i < par.length; i++) {
|
String a = par[i].split("=")[0];
|
String v = par[i].split("=")[1];
|
if (a.equals("validateNumber")) {
|
String validateurl = "http://192.168.4.50/services/PortalLoginService/ValidLoginUser?validateNumber="
|
+ v;
|
try {
|
result = HttpUtils.get(validateurl);
|
} catch (Exception e) {
|
logger.info(result);
|
e.printStackTrace();
|
}
|
}
|
if (a.equals("userName")) {
|
username = v;
|
}
|
}
|
int start = result.indexOf("<ns:return>");
|
int end = result.indexOf("</ns:return>");
|
if (start != -1 && end != -1) {
|
JSONObject json = JSONObject.parseObject(result.substring(start + 11, end));
|
json.put("username", username);
|
|
return json;
|
}
|
}
|
return null;
|
|
}
|
|
/**
|
* CAS登陆成功后调用此方法创建本系统的token
|
*
|
* @param request
|
* @param response
|
* @return
|
* @throws Exception
|
*/
|
@LogLogininfo("登录")
|
@RequestMapping(value = "/login", method = RequestMethod.GET)
|
public void login(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
String username = request.getRemoteUser();
|
if (StringUtils.hasText(username)) {// 已经登录shiro
|
String oldUrl = getOldParameterPath(request);
|
response.sendRedirect(oldUrl);
|
// WebUtils.issueRedirect(request, response, oldUrl);
|
// } else {
|
//
|
// // oa门户登录判断
|
// JSONObject validateresult = portallogin(request);
|
// if (validateresult != null && "true".equals(validateresult.getString("validateResult"))) {
|
// String oldUrl = getOldParameterPath(request);
|
// Subject subject = SecurityUtils.getSubject();
|
// ShiroToken shiroToken = new ShiroToken(validateresult.getString("username"), true);
|
// subject.login(shiroToken);
|
// WebUtils.issueRedirect(request, response, oldUrl);
|
} else {
|
|
username = getLoginNamefromXml(request);
|
// username="kanglinchong";
|
// username="liujin";
|
// username="hanzhicong";
|
|
if (StringUtils.hasText(username)) {
|
OrgUser user = orgUserService.queryByUserName(username);
|
// 账号不存在
|
if (user == null) {
|
response.getWriter().write("[" + username + "]账号不存在或未注册到系统");
|
return;
|
}
|
Subject subject = SecurityUtils.getSubject();
|
ShiroToken shiroToken = new ShiroToken(username, true);
|
|
if (!subject.isAuthenticated()) {
|
subject.login(shiroToken);
|
logger.debug("8----loginshiro:");
|
}
|
//这里算用户登录成功 ,存入名称和当前毫秒数kv入在线map add by zsx
|
|
onlineUserRedis.saveOnlineUser(username,subject.getSession());
|
|
|
Session session = subject.getSession(true);
|
session.setAttribute("shirousername", username);
|
// session.setMaxInactiveInterval(sysConfig.getSessionTimeOut());//
|
// 设置Session的超时时间
|
// 单位秒
|
logger.debug("3----shirousername:" + session.getAttribute("shirousername").toString()
|
+ (session.getId()));
|
String oldUrl = getOldQueryString(request);
|
|
logger.debug("3----RedirectOldurl:" + oldUrl);
|
// WebUtils.issueRedirect(request, response, oldUrl);
|
response.sendRedirect(oldUrl);
|
} else {
|
String CasHost = sysConfig.getCasHost();// https://cas.nmsmp.com/cas/
|
String loginUrl = sysConfig.getLoginUrl(); // http://127.0.0.1:8082/login
|
String oldurl = getOldSessionPath(request);
|
if (StringUtils.hasText(oldurl)) {
|
CasHost += "login?service=" + loginUrl + "?oldurl=" + URLEncoder.encode(oldurl);
|
}
|
logger.debug("1----RedirectCasloginUrl:" + CasHost);
|
response.sendRedirect(CasHost);// 用户名不存在跳转回登录页面
|
}
|
}
|
}
|
|
|
private String getOldQueryString(HttpServletRequest request) {
|
String server = request.getQueryString();
|
String ticket = request.getParameter("ticket");
|
if (!org.springframework.util.StringUtils.isEmpty(ticket)) {
|
server = server.replace("ticket=" + ticket, "");
|
if (server.endsWith("&"))
|
server = server.substring(0, server.length() - 1);
|
}
|
server = server.replace("oldurl=", "");
|
return server;
|
}
|
|
/***
|
* 获取原始访问路径
|
*
|
* @return
|
*/
|
private String getOldParameterPath(HttpServletRequest request) {
|
String oldUrl = request.getParameter("oldurl");
|
oldUrl = (oldUrl == null) ? "/" : oldUrl;
|
return oldUrl;
|
}
|
|
/***
|
* 获取原始访问路径
|
*
|
* @return
|
*/
|
private String getOldSessionPath(HttpServletRequest request) {
|
String oldurl = getOldParameterPath(request);
|
if (oldurl == "/") {
|
Subject subject = SecurityUtils.getSubject();
|
Session session = subject.getSession();
|
SavedRequest req = (SavedRequest) session.getAttribute(WebUtils.SAVED_REQUEST_KEY);
|
oldurl = (req == null) ? "" : req.getRequestUrl();
|
}
|
return oldurl;
|
}
|
|
/**
|
* CAS登陆成功后调用此方法创建本系统的token 返回jsonp
|
*
|
* @param request
|
* @param response
|
* @return
|
*/
|
@LogLogininfo("登录")
|
@RequestMapping(value = "/sys/caslogin2", method = RequestMethod.GET)
|
@ResponseBody
|
public String caslogin2(HttpServletRequest request, HttpServletResponse response) {
|
String callbackFunName = request.getParameter("callback"); // js回调函数名称
|
if (callbackFunName == null || callbackFunName.isEmpty()) {
|
callbackFunName = "casloginCallback";
|
}
|
response.setCharacterEncoding("utf-8");
|
response.setContentType("text/plain");
|
return "";// getJsonp(caslogin(request, response), callbackFunName);
|
}
|
|
/**
|
* 转化为jsonp字符串
|
*
|
* @param map
|
* @param callbackFunName
|
* @return
|
*/
|
private String getJsonp(Map<String, Object> map, String callbackFunName) {
|
String jsonp = JSONUtils.toJSONString(map);
|
return callbackFunName + "(" + jsonp + ")";
|
}
|
|
/**
|
* 退出
|
*
|
* @throws IOException
|
*/
|
@LogLogininfo("登出")
|
@RequestMapping(value = "/logout")
|
public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
Subject subject = SecurityUtils.getSubject();
|
|
|
subject.logout();
|
////移除在线人数 add by zsx
|
onlineUserRedis.cleanLogoutUser(subject.getSession());
|
|
|
String CasHost = sysConfig.getCasHost();
|
String logoutUrl = CasHost + "logout?service=" + CasHost + "login";
|
WebUtils.issueRedirect(request, response, logoutUrl);
|
|
// sysUserTokenService.logout(getUserId());
|
// return Result.ok();
|
}
|
|
/**
|
* 从session中获取记录的验证码
|
*/
|
private String getKaptcha(String key) {
|
Object kaptcha = ShiroUtils.getSessionAttribute(key);
|
if (kaptcha == null) {
|
throw new LanbaseException("验证码已失效");
|
}
|
ShiroUtils.getSession().removeAttribute(key);
|
return kaptcha.toString();
|
}
|
|
|
// /**
|
// * 定时判断,查询用户最近一次操作时间 若最近一次时间超过5分钟,则判断用户下线
|
// */
|
// @Scheduled(fixedRate=2*60*1000)
|
// public void cleanMayDownUser(){
|
// onlineUserRedis.removeDownlineUser();
|
// }
|
|
}
|