package com.dsideal.Sso.Controller; import cn.hutool.captcha.CaptchaUtil; import cn.hutool.captcha.LineCaptcha; import com.alibaba.fastjson.JSONObject; import com.dsideal.Interceptor.EmptyInterface; import com.dsideal.Sso.Model.BaseModel; import com.dsideal.Util.*; import com.jfinal.aop.Before; import com.jfinal.core.Controller; import com.jfinal.ext.interceptor.GET; import com.jfinal.ext.interceptor.POST; import com.jfinal.kit.Kv; import com.jfinal.kit.PropKit; import com.jfinal.kit.StrKit; import com.jfinal.plugin.activerecord.Record; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Set; public class WebLoginController extends Controller { @Before({GET.class}) public void index() { redirect("/html/login.html"); } @Before({GET.class}) @EmptyInterface({"redirect_url"}) public void login(String redirect_url) { Set _set = RedisKit.SMembers(PropKit.get("SYS_JRXT")); boolean found = false; for (String s : _set) { if (redirect_url.indexOf(s) >= 0) { found = true; break; } } if (!found) { JSONObject resultJson = new JSONObject(); resultJson.put("success", false); resultJson.put("msg", "回调地址不在指定的IP或域名范围内!"); renderJson(resultJson); return; } Kv kv = SsoLoginHelper.loginCheck(getRequest()); if (kv.getBoolean("success")) { String ssoSessionId = PropKit.get("sso.sessionid"); if (redirect_url.indexOf("?") == -1) { redirect301(redirect_url + "?" + ssoSessionId + "=" + kv.getStr("session_id")); } else { redirect301(redirect_url + "&" + ssoSessionId + "=" + kv.getStr("session_id")); } } else { redirect_url = CommonUtil.handleRedirectUrlParas(redirect_url); redirect("/html/login.html?redirect_url=" + redirect_url); } } /** * WEB登录 */ @Before({POST.class}) public void doLogin(String username, String password, String captcha) { JSONObject resultJson = new JSONObject(); if (StrKit.isBlank(captcha)) { resultJson.put("success", false); resultJson.put("msg", "验证码不能为空!"); renderJson(resultJson); return; } if (SessionKit.get(getRequest(), getResponse(), "captcha") == null) { resultJson.put("success", false); resultJson.put("msg", "在浏览器会话中没有检查到验证码,你的行为将会记录!"); renderJson(resultJson); return; } String memory_captcha = SessionKit.get(getRequest(), getResponse(), "captcha"); //验证码错误次数 String checkCodeKey = "Yzm_error_" + username; int CheckCodeErrCnt = 4; //最多允许错几次 4+1 int CheckCodecntNum = 0; //错几次了 if (RedisKit.Exists(checkCodeKey)) CheckCodecntNum = Integer.parseInt(RedisKit.Get(checkCodeKey)); if (CheckCodecntNum > CheckCodeErrCnt) { resultJson.put("success", false); resultJson.put("msg", "账号已被停用5分钟,请稍后再试!"); renderJson(resultJson); return; } if (!memory_captcha.equals(captcha.toLowerCase())) { CheckCodecntNum = 1; if (RedisKit.Exists(checkCodeKey)) CheckCodecntNum = Integer.parseInt(RedisKit.Get(checkCodeKey)) + CheckCodecntNum; int finalCheckCodecntNum = CheckCodecntNum; RedisKit.incrBy(checkCodeKey, finalCheckCodecntNum); RedisKit.Expire(checkCodeKey, 60 * 5); if (CheckCodecntNum == CheckCodeErrCnt) { resultJson.put("success", false); resultJson.put("msg", "验证码连续输入错误" + CheckCodecntNum + "次,再错误一次将被封号5分钟!"); renderJson(resultJson); return; } if (CheckCodecntNum > CheckCodeErrCnt) { resultJson.put("success", false); resultJson.put("msg", "验证码连续输入错误5次,账号被停用5分钟,请稍后再试!"); renderJson(resultJson); return; } resultJson.put("success", false); resultJson.put("msg", "验证码不正确!"); renderJson(resultJson); return; } if (StrKit.isBlank(username)) { resultJson.put("success", false); resultJson.put("msg", "用户名不允许为空!"); renderJson(resultJson); return; } if (StrKit.isBlank(password)) { resultJson.put("success", false); resultJson.put("msg", "密码不允许为空!"); renderJson(resultJson); return; } //检查缓存中此账号错误了几次 String PassWordKey = "WrongPassWord_" + username; int ErrCnt = 4; //最多允许错几次 4+1 int cntNum = 0; //错几次了 if (RedisKit.Exists(PassWordKey)) cntNum = Integer.parseInt(RedisKit.Get(PassWordKey)); if (cntNum > ErrCnt) { resultJson.put("success", false); resultJson.put("msg", "账号被停用5分钟,请稍后再试!"); renderJson(resultJson); return; } //与前端配合RSA通用加密解密 try { password = RsaUtils.decryptDataOnJava(password, RsaUtils.PRIVATEKEY); } catch (Exception err) { password = "!@#$%^&&*^*&(*)(*_)^%^$%$^%$^%"; } String passwordEncode = CommonUtil.getLdapPassword(password); BaseModel bm = new BaseModel(); Record loginMap = bm.getLoginInfoByUserName(username); if (loginMap == null || !passwordEncode.equals(loginMap.get("pwd").toString())) { //扩展支持连续输入用户名密码错误,停用账号5分钟功能 2022.06.07 cntNum = 1; if (RedisKit.Exists(PassWordKey)) cntNum = Integer.parseInt(RedisKit.Get(PassWordKey)) + cntNum; int finalCntNum = cntNum; RedisKit.incrBy(PassWordKey, finalCntNum); RedisKit.Expire(PassWordKey, 60 * 5); if (cntNum > ErrCnt) { resultJson.put("success", false); resultJson.put("msg", "密码连续输入" + (ErrCnt + 1) + "次全部错误,账号将被停用5分钟!"); renderJson(resultJson); return; } if (cntNum == ErrCnt) { resultJson.put("success", false); resultJson.put("msg", "用户名或密码连续错误,你还有1次机会,再次错误后账号将被封掉5分钟!"); renderJson(resultJson); return; } resultJson.put("success", false); resultJson.put("msg", "用户名或密码错误!"); renderJson(resultJson); return; } //去掉限制 RedisKit.Del(PassWordKey); RedisKit.Del(checkCodeKey); SessionKit.set(getRequest(), getResponse(), "identity_id", loginMap.get("identity_id").toString()); SessionKit.set(getRequest(), getResponse(), "person_id", loginMap.get("person_id").toString()); resultJson.put("success", true); String jSessionId = SessionKit.getCookieSessionId(getRequest(), getResponse()); resultJson.put("token", jSessionId); SsoLoginHelper.login(getResponse(), jSessionId, loginMap); renderJson(resultJson); } /** * WEB登出 */ @Before({GET.class}) @EmptyInterface({"redirect_url"}) public void logout(String redirect_url) { SsoLoginHelper.logout(getRequest(), getResponse()); SessionKit.clear(getRequest(), getResponse()); redirect(redirect_url); } /** * 获取验证码 */ @Before({GET.class}) public void getCaptcha() throws IOException { HttpServletResponse response = getResponse(); // 设置相应类型,告诉浏览器输出的内容为图片 response.setContentType("image/jpeg"); // 不缓存此内容 response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expire", 0); LineCaptcha captcha = CaptchaUtil.createLineCaptcha(80, 42, 4, 10); // 重新生成code captcha.createCode(); //写入session SessionKit.set(getRequest(), getResponse(), "captcha", captcha.getCode()); // 将内存中的图片通过流动形式输出到客户端 captcha.write(response.getOutputStream()); renderNull(); } /** * 功能:委托登录 * http://10.10.21.20:9001/dsssoserver/login?redirect_url=http://www.163.com/&random=123 需要加上随机数,否则会有浏览器缓存影响测试 *

* 功能:票据验证 * http://10.10.21.20:9001/dsssoserver/check?token=2b4e9cc4-9357-45bf-a367-b61b0b5f4387 *

* 上线前根据t_datashare_system中配置的服务器ip地址进行访问权限验证,目前不加限制 */ @Before({GET.class}) @EmptyInterface({"token"}) public void check(String token) { JSONObject resultJson = new JSONObject(); Kv kv = SsoLoginHelper.loginCheck(token); if (!kv.getBoolean("success")) { resultJson.put("success", false); resultJson.put("token", token); resultJson.put("message", "统一认证票据验证失败!"); } else { resultJson.put("success", true); resultJson.put("identity_id", kv.getStr("identity_id")); resultJson.put("person_id", kv.getStr("person_id")); resultJson.put("message", "统一认证票据正确!"); resultJson.put("token", token); } renderJson(resultJson); } }