package com.landtool.lanbase.modules.sys.controller;
|
|
import com.alibaba.druid.support.json.JSONUtils;
|
import com.alibaba.fastjson.JSONObject;
|
import com.fasterxml.jackson.databind.ser.std.StdKeySerializers.Default;
|
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.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;
|
import org.apache.commons.io.IOUtils;
|
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.session.Session;
|
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
|
import org.apache.shiro.session.mgt.eis.SessionDAO;
|
import org.apache.shiro.subject.SimplePrincipalCollection;
|
import org.apache.shiro.subject.Subject;
|
import org.apache.shiro.subject.support.DefaultSubjectContext;
|
import org.apache.shiro.util.StringUtils;
|
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
|
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.beans.factory.annotation.Value;
|
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 org.springframework.web.servlet.ModelAndView;
|
import org.springframework.beans.factory.annotation.Value;
|
import javax.imageio.ImageIO;
|
import javax.servlet.ServletException;
|
import javax.servlet.ServletOutputStream;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
|
import java.awt.image.BufferedImage;
|
import java.io.IOException;
|
import java.net.URLEncoder;
|
import java.util.Collection;
|
import java.util.Map;
|
|
/**
|
* @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;
|
/**
|
* 首页
|
* @param request
|
* @param response
|
* @throws IOException
|
*/
|
@RequestMapping(value = "/", method = RequestMethod.GET)
|
public void hutaiadmin(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
response.sendRedirect("/lanwebapp/admin/index.html");
|
}
|
|
@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);
|
}
|
|
|
/**
|
* 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;
|
|
|
}
|
|
/**
|
* 登录
|
*/
|
@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 = "";
|
// 判断ticket
|
// String CASHOST = "https://www.lt.com:8443/cas/";
|
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 + "登陆成功!");
|
}
|
|
/**
|
* 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);
|
WebUtils.issueRedirect(request, response, oldUrl);
|
} else {
|
username = getLoginNamefromXml(request);
|
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);
|
subject.login(shiroToken);
|
onlineUserRedis.saveOnlineUser(username,subject.getSession());
|
String oldUrl = getOldQueryString(request);
|
|
logger.debug("3----RedirectOldurl:" + oldUrl);
|
WebUtils.issueRedirect(request, response, 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();
|
onlineUserRedis.cleanLogoutUser(subject.getSession());
|
subject.logout();
|
|
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();
|
}
|
|
/**
|
* 从session中获取记录的验证码
|
*/
|
private Session getSessionByUsername(String username) {
|
DefaultWebSecurityManager securityManager=(DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
|
DefaultWebSessionManager sessionManager=(DefaultWebSessionManager) securityManager.getSessionManager();
|
Collection<Session> sessions=sessionManager.getSessionDAO().getActiveSessions();
|
Object attribute;
|
String user;
|
Session ses = null;
|
for(Session session:sessions){
|
attribute=session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
|
user=((SimplePrincipalCollection) attribute).toString();
|
if(user.equals(username)){
|
ses=session;
|
session.stop();
|
break;
|
|
}
|
}
|
return ses;
|
}
|
|
|
/**
|
* 退出
|
* @throws IOException
|
*/
|
@LogLogininfo("登出")
|
@RequestMapping(value = "/tick")
|
public void tickSomeOneDown(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
Subject subject = SecurityUtils.getSubject();
|
|
onlineUserRedis.cleanLogoutUser(subject.getSession());
|
subject.logout();
|
|
String CasHost= sysConfig.getCasHost();
|
String logoutUrl=CasHost+"logout?service="+CasHost+"login";
|
WebUtils.issueRedirect(request, response, logoutUrl);
|
//sysUserTokenService.logout(getUserId());
|
//return Result.ok();
|
}
|
|
|
}
|