You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

253 lines
10 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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<String> _set = RedisKit.SMembers(PropKit.get("SYS_JRXT"));
boolean found = false;
for (String s : _set) {
if (redirect_url.contains(s)) {
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.contains("?")) {
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 (passwordEncode != null && (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);
}
}