188 lines
7.8 KiB
Java
188 lines
7.8 KiB
Java
package lingtao.net.realm;
|
||
|
||
import com.github.pagehelper.util.StringUtil;
|
||
import lingtao.net.bean.LoginLog;
|
||
import lingtao.net.bean.SysPermission;
|
||
import lingtao.net.bean.SysUser;
|
||
import lingtao.net.dao.LoginIpMapper;
|
||
import lingtao.net.dao.LoginLogMapper;
|
||
import lingtao.net.dao.SysPermissionMapper;
|
||
import lingtao.net.dao.SysUserMapper;
|
||
import lingtao.net.util.DateFormatUtils;
|
||
import lingtao.net.util.LunarCalendarUtil;
|
||
import org.apache.shiro.SecurityUtils;
|
||
import org.apache.shiro.authc.*;
|
||
import org.apache.shiro.authz.AuthorizationInfo;
|
||
import org.apache.shiro.realm.AuthorizingRealm;
|
||
import org.apache.shiro.session.Session;
|
||
import org.apache.shiro.session.mgt.eis.SessionDAO;
|
||
import org.apache.shiro.subject.PrincipalCollection;
|
||
import org.apache.shiro.subject.support.DefaultSubjectContext;
|
||
import org.apache.shiro.util.SimpleByteSource;
|
||
import org.springframework.beans.factory.annotation.Autowired;
|
||
|
||
import java.text.ParseException;
|
||
import java.text.SimpleDateFormat;
|
||
import java.util.Collection;
|
||
import java.util.Date;
|
||
import java.util.List;
|
||
|
||
public class ShiroRealm extends AuthorizingRealm {
|
||
@Autowired
|
||
private SysUserMapper userMapper;
|
||
@Autowired
|
||
private SysPermissionMapper sysPermissionMapper;
|
||
@Autowired
|
||
private LoginIpMapper loginIpMapper;
|
||
@Autowired
|
||
private LoginLogMapper loginLogMapper;
|
||
@Autowired
|
||
private SessionDAO sessionDAO;
|
||
// 日期格式化
|
||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||
|
||
// 授权
|
||
@Override
|
||
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
|
||
// TODO Auto-generated method stub
|
||
return null;
|
||
}
|
||
|
||
private boolean ipIsInWildCardNoCheck(String ipWildCard, String ip) {
|
||
String[] s1 = ipWildCard.split("\\.");
|
||
String[] s2 = ip.split("\\.");
|
||
boolean isMatchedSeg = true;
|
||
for (int i = 0; i < s1.length && !s1[i].equals("*"); i++) {
|
||
if (!s1[i].equals(s2[i])) {
|
||
isMatchedSeg = false;
|
||
break;
|
||
}
|
||
}
|
||
return isMatchedSeg;
|
||
}
|
||
|
||
private boolean isPassIp(String loginIp) {
|
||
// 获取所有的授权IP
|
||
List<String> ipList = loginIpMapper.getAllIp();
|
||
if(loginIp == "127.0.0.1"){
|
||
return true;
|
||
}
|
||
for (String agreeIp : ipList) {
|
||
// 如果当前登录的IP在授权IP中
|
||
if (ipIsInWildCardNoCheck(agreeIp, loginIp)) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
|
||
// 登录验证
|
||
@Override
|
||
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
|
||
UsernamePasswordToken token2 = (UsernamePasswordToken) token;
|
||
// String username = token2.getUsername();
|
||
SimpleAuthenticationInfo info = null;
|
||
|
||
// 从token中取出用户名
|
||
String username = (String) token.getPrincipal();
|
||
// String username = "admin";
|
||
SysUser user = userMapper.getUserByUsername(username);
|
||
|
||
if (user != null) {
|
||
if ("0".contentEquals(user.getUserStatus())) {
|
||
throw new LockedAccountException("用户未激活,请联系管理员");
|
||
}
|
||
/** 处理账号只能在授权的IP中登录 */
|
||
// 是否允许登录标识
|
||
boolean agreeLogin = true;
|
||
// 当前登录用户的IP地址
|
||
// String loginIp = SecurityUtils.getSubject().getSession().getHost();
|
||
String loginIp = token2.getHost();
|
||
System.out.println("当前登录用户的IP地址:" + loginIp);
|
||
// 登录说明
|
||
String loginRemark = formatter.format(new Date()) + "【" + user.getRealname() + " - " + username + "】 IP:" + loginIp;
|
||
LoginLog loginLog = new LoginLog();
|
||
if (isPassIp(loginIp)) {
|
||
loginRemark += "--已知IP";
|
||
loginLog.setStatus("正常");
|
||
agreeLogin = true;
|
||
} else {
|
||
loginRemark += "--未知IP";
|
||
loginLog.setStatus("异常");
|
||
agreeLogin = false;
|
||
}
|
||
|
||
loginLog.setLoginTime(new Date());
|
||
loginLog.setRemark(loginRemark);
|
||
loginLogMapper.addLog(loginLog);
|
||
|
||
if (!agreeLogin) {
|
||
throw new AuthenticationException("IP受限" + loginIp);
|
||
}
|
||
|
||
/** 处理生日 */
|
||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||
Date birthDate = null;
|
||
String birthDay = "";
|
||
// 生日日期/类型不为空
|
||
if (StringUtil.isNotEmpty(user.getBirthDay()) && StringUtil.isNotEmpty(user.getBirthType())) {
|
||
// 如果是新历生日,直接获取生日日期
|
||
if (user.getBirthType().equals("1")) {
|
||
birthDay = String.format("%tY", new Date()) + "-" + user.getBirthDay();
|
||
} else if (user.getBirthType().equals("0")) {// 如果是农历生日
|
||
// 先将农历生日转换成新历;调用工具类转换,使用String.format获取年、月、日
|
||
int[] lunarToSolar = LunarCalendarUtil.lunarToSolar(
|
||
Integer.valueOf(String.format("%tY", new Date())),
|
||
Integer.valueOf(user.getBirthDay().split("-")[0]),
|
||
Integer.valueOf(user.getBirthDay().split("-")[1]), true);
|
||
for (int i = 0; i < 3; i++) {
|
||
birthDay += lunarToSolar[i] + "-";
|
||
}
|
||
birthDay = birthDay.substring(0, birthDay.length() - 1);
|
||
}
|
||
try {
|
||
birthDate = sdf.parse(birthDay);
|
||
// 如果当天生日,改变状态
|
||
if (Math.abs(DateFormatUtils.getSubtractiveDays(birthDate, new Date())) == 0) {
|
||
// 生日:1
|
||
userMapper.setIsBirthDay(1, user.getUserId());
|
||
}
|
||
} catch (ParseException e) {
|
||
// e.printStackTrace();
|
||
}
|
||
}
|
||
|
||
/** 处理session(将用户信息存入session) */
|
||
// 将用户信息存入session
|
||
SecurityUtils.getSubject().getSession().setAttribute("USER_SESSION", user);
|
||
// 获取权限列表
|
||
List<SysPermission> persList = sysPermissionMapper.getPersByUserId(user.getUserId());
|
||
// 将权限list存入session
|
||
SecurityUtils.getSubject().getSession().setAttribute("USERPERS_SESSION", persList);
|
||
info = new SimpleAuthenticationInfo(user, user.getPassword(), new SimpleByteSource("lingtao"), getName());
|
||
// 设置session过期时间(毫秒) :正负都可以,为负数时表示永不超时。
|
||
SecurityUtils.getSubject().getSession().setTimeout(1000 * 60 * 60 * 14);
|
||
|
||
/** 处理session(账号只允许同时一人登录) */
|
||
// shiro获取所有在线用户
|
||
Collection<Session> sessionsCollections = sessionDAO.getActiveSessions();
|
||
// 遍历所有的在线用户
|
||
for (Session session : sessionsCollections) {
|
||
// 获得session中已经登录的单个用户对象
|
||
String loginUsername = String
|
||
.valueOf(session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY));
|
||
// 这里的user对象也就是当前登录的loginUsername对象,判断当前登录的用户是否已是在线用户,是的话就清除
|
||
if (String.valueOf(user).equals(loginUsername)) {
|
||
// 这里就把session清除,
|
||
session.setTimeout(0);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
// 框架完成验证
|
||
return info;
|
||
}
|
||
|
||
}
|