| | |
| | | package com.whyc.service; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.whyc.constant.UserConstant; |
| | | import com.whyc.constant.YamlProperties; |
| | | import com.whyc.dto.Response; |
| | | import com.whyc.mapper.PageParamMapper; |
| | | import com.whyc.mapper.PermitGroupUserMapper; |
| | | import com.whyc.mapper.UserMapper; |
| | | import com.whyc.pojo.PageParam; |
| | | import com.whyc.pojo.UserClient; |
| | | import com.whyc.pojo.UserInf; |
| | | import com.whyc.util.ActionUtil; |
| | |
| | | import org.apache.shiro.subject.Subject; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.ServletContext; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpSession; |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.net.URLDecoder; |
| | | import java.util.Map; |
| | | import java.util.*; |
| | | |
| | | @Service |
| | | public class LoginService { |
| | | |
| | | @Resource |
| | | private UserMapper userMapper; |
| | | |
| | | @Resource |
| | | private UserService userService; |
| | | |
| | | @Resource |
| | | private PermitGroupUserService permitGroupUserService; |
| | | |
| | | @Resource |
| | | private PageParamMapper pageParamMapper; |
| | | |
| | | public Response login(String userName, String password, HttpServletRequest request) { |
| | | UsernamePasswordToken userToken = new UsernamePasswordToken(userName, password); |
| | |
| | | } |
| | | return new Response<>().set(1,false,"密码错误"); |
| | | } |
| | | |
| | | public Response loginByRSA(String userName, String pwd,String deliveredCode, HttpServletRequest request) { |
| | | Response<Object> response = new Response<>(); |
| | | deliveredCode = deliveredCode.toUpperCase(); |
| | | String fontDynamicCode = (String) ActionUtil.getSession().getAttribute("fontDynamicCode"); |
| | | if (fontDynamicCode==null||"".equals(fontDynamicCode)){ |
| | | return new Response().set(1,false,"请刷新验证码"); |
| | | return response.set(1,false,"请刷新验证码"); |
| | | } |
| | | if (!deliveredCode.equals(fontDynamicCode.toUpperCase())){ |
| | | return new Response().set(1,false,"验证码错误"); |
| | | return response.set(1,false,"验证码错误"); |
| | | } |
| | | //验证正确,清除验证码 |
| | | ActionUtil.getSession().removeAttribute("fontDynamicCode"); |
| | |
| | | String[] dataArr = RSAUtil.decryptFront(password, RSAUtil.fontSeparator); |
| | | //验签md5 |
| | | if(!dataArr[1].equals(ActionUtil.EncryptionMD5(org.apache.commons.lang3.StringUtils.trim(dataArr[0])).toString())){ |
| | | return new Response<>().set(0,"密码验签失败"); |
| | | return response.set(1,false,"密码验签失败"); |
| | | } |
| | | UsernamePasswordToken userToken = new UsernamePasswordToken(userName, dataArr[0]); |
| | | Subject subject = SecurityUtils.getSubject(); |
| | |
| | | }catch (Exception e){ |
| | | String message = e.getMessage(); |
| | | if(message.contains("did not match the expected credentials")){ |
| | | return new Response<>().set(1,false,"密码错误"); |
| | | return response.set(1,false,"密码错误"); |
| | | } |
| | | return new Response<>().set(1,false,message); |
| | | return response.set(1,false,message); |
| | | } |
| | | ServletContext servletContext = request.getServletContext(); |
| | | Enumeration<String> attributeNames = servletContext.getAttributeNames(); |
| | | |
| | | QueryWrapper<UserInf> queryWrapper = Wrappers.query(); |
| | | queryWrapper.select("uId","status","visit_ip","visit_time","password_update_time","last_login_time").eq("uName",userName); |
| | | UserInf userInf = userMapper.selectOne(queryWrapper); |
| | | if (subject.isAuthenticated()){ |
| | | //每个登录的用户都有一个全局变量,里面存着对应的SessionId; |
| | | //同一个账号,后面登录的,会挤掉之前登录的SessionId,这个todo,做限制账号同时登陆人数为1 |
| | | request.getServletContext().setAttribute(userName,request.getSession().getId()); |
| | | //Session存储当前用户 |
| | | |
| | | //查询账号状态 |
| | | if(userInf.getStatus()!=1){ |
| | | switch (userInf.getStatus()){ |
| | | case 0: response.setMsg("当前账号的状态异常,无法登录. 异常信息为: "+ UserConstant.ACCOUNT_STATUS_CANCEL.getLabel());break; |
| | | case 2: response.setMsg("当前账号的状态异常,无法登录. 异常信息为: "+ UserConstant.ACCOUNT_STATUS_HIBERNATE.getLabel());break; |
| | | case 3: response.setMsg("当前账号的状态异常,无法登录. 异常信息为: "+ UserConstant.ACCOUNT_STATUS_LOCK.getLabel());break; |
| | | case 4: response.setMsg("当前账号的状态异常,无法登录. 异常信息为: "+ UserConstant.ACCOUNT_STATUS_LOCK_FAIL.getLabel());break; |
| | | default:response.setMsg("当前账号的状态异常,无法登录. 异常信息为: 无"); |
| | | } |
| | | return response.set(1,false); |
| | | } |
| | | |
| | | //严格标准下的规则校验 |
| | | if(YamlProperties.systemType == 2){ |
| | | //登录之前,首先校验允许时间和登录ip |
| | | boolean ipPass = true; |
| | | |
| | | String firstTime = userInf.getVisitTime().split("~")[0]; |
| | | String lastTime = userInf.getVisitTime().split("~")[1]; |
| | | |
| | | List<String> ipRules = new LinkedList<>(); |
| | | String ipRuleStr = userInf.getVisitIp(); |
| | | ipRules = Arrays.asList(ipRuleStr.split(",")); |
| | | |
| | | Calendar instance = Calendar.getInstance(); |
| | | String hourOfDay = String.format("%1$02d",instance.get(Calendar.HOUR_OF_DAY)); |
| | | int minute = instance.get(Calendar.MINUTE); |
| | | int second = instance.get(Calendar.SECOND); |
| | | String nowTime = hourOfDay+":"+minute+":"+second; |
| | | //登录时间校验 |
| | | if(nowTime.compareTo(firstTime)>=0 && nowTime.compareTo(lastTime)<=0){ |
| | | //登录ip校验 |
| | | String clientIp = ActionUtil.getRequest().getRemoteAddr(); |
| | | if(!ipRules.contains("*")){ |
| | | for(String ipRule:ipRules){ |
| | | ipPass = true; |
| | | //ip规则格式为 * 或者 xxx.xxx.x.x |
| | | String[] ipArr = clientIp.split("\\."); |
| | | String[] ipRuleArr = ipRule.split("\\."); |
| | | for (int i = 0; i < ipRuleArr.length; i++) { |
| | | if(!ipRuleArr[i].equals("*") && !ipRuleArr[i].equals(ipArr[i])){ |
| | | ipPass = false; |
| | | break; |
| | | } |
| | | } |
| | | if(ipPass){ |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | if(!ipPass){ |
| | | return response.set(1,false,"您的IP禁止访问,请知晓"); |
| | | } |
| | | }else{ |
| | | return response.set(1,false,"登录时间不在允许的时间范围内"); |
| | | } |
| | | //首次登录,密码修改;超过3个月未修改密码,强制修改密码 |
| | | Date passwordUpdateTime = userInf.getPasswordUpdateTime(); |
| | | Calendar now = Calendar.getInstance(); |
| | | now.add(Calendar.MONTH,-3); |
| | | if(passwordUpdateTime==null){ //密码修改时间为空,尚未修改初始口令 |
| | | response.setCode(3); |
| | | response.setData(false); |
| | | response.setMsg("首次登录,请先修改初始化口令"); |
| | | return response; |
| | | } |
| | | else if(passwordUpdateTime.compareTo(now.getTime()) < 0){ |
| | | response.setCode(2); |
| | | response.setData(false); |
| | | response.setMsg("超过3个月没有修改口令,请修改口令后重新登录"); |
| | | return response; |
| | | } |
| | | } |
| | | |
| | | //登录成功 |
| | | servletContext.setAttribute(userName,request.getSession().getId()); |
| | | //Session存储当前用户及权限组列表 |
| | | request.getSession().setAttribute("user",subject.getPrincipal()); |
| | | return new Response<>().setII(1,true,subject.getPrincipal(),"登录成功"); |
| | | request.getSession().setAttribute("permits",ActionUtil.getGson().toJson(permitGroupUserService.getItemList(userInf.getUId()))); |
| | | //清除账号登录失败记录 |
| | | while (attributeNames.hasMoreElements()){ |
| | | String attributeName = attributeNames.nextElement(); |
| | | if(attributeName.contains(userName +"_login_fail_times_")){ |
| | | servletContext.removeAttribute(attributeName); |
| | | } |
| | | } |
| | | //回写登录时间到数据库 |
| | | userService.updateLoginTime(userInf.getUId()); |
| | | //查询用户对应的权限组id并返回给前端 |
| | | LinkedList<Object> dataList = new LinkedList<>(); |
| | | dataList.add(subject.getPrincipal()); |
| | | int permitGroupId = permitGroupUserService.getPermitGroupId(userInf.getUId()); |
| | | dataList.add(permitGroupId); |
| | | return new Response<>().setII(1,true,dataList,"登录成功"); |
| | | } |
| | | |
| | | //密码错误,记录次数 |
| | | //内存中查找该用户中的登录失败次数 |
| | | int loginFailTimes = 0; |
| | | List<String> loginFailAttributeList = new LinkedList<>(); |
| | | while (attributeNames.hasMoreElements()){ |
| | | String attributeName = attributeNames.nextElement(); |
| | | if(attributeName.contains(userName+"_login_fail_times_")){ |
| | | loginFailTimes++; |
| | | loginFailAttributeList.add(attributeName); |
| | | } |
| | | } |
| | | //查询账号密码错误限制次数 |
| | | PageParam loginFailTimesLimit = pageParamMapper.findByCategoryId(9).get(0); |
| | | if((++loginFailTimes)==loginFailTimesLimit.getStatus()){ |
| | | //达到限制次数,锁定账号 |
| | | userService.lock(userInf.getUId()); |
| | | //清除登录错误次数统计 |
| | | loginFailAttributeList.forEach(servletContext::removeAttribute); |
| | | }else { |
| | | servletContext.setAttribute(userName + "_login_fail_times_"+System.currentTimeMillis(), 0); |
| | | } |
| | | return new Response<>().set(1,false,"密码错误"); |
| | | } |