|
@@ -2,27 +2,36 @@ package com.jd.lightapplication.security;
|
|
|
|
|
|
import cn.hutool.core.codec.Base64;
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
import cn.hutool.http.HttpUtil;
|
|
|
import cn.hutool.json.JSONObject;
|
|
|
import cn.hutool.json.JSONUtil;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.jd.lightapplication.common.exception.CaptchaException;
|
|
|
import com.jd.lightapplication.common.lang.R;
|
|
|
import com.jd.lightapplication.common.lang.WeChatConfig;
|
|
|
import com.jd.lightapplication.easemob.EasemobComtroller;
|
|
|
import com.jd.lightapplication.easemob.dto.EasemobUserAddDto;
|
|
|
+import com.jd.lightapplication.model.ConfigInfo;
|
|
|
import com.jd.lightapplication.model.SysRole;
|
|
|
import com.jd.lightapplication.model.SysUser;
|
|
|
import com.jd.lightapplication.model.SysUserRole;
|
|
|
+import com.jd.lightapplication.service.ConfigInfoService;
|
|
|
import com.jd.lightapplication.service.SysRoleService;
|
|
|
import com.jd.lightapplication.service.SysUserRoleService;
|
|
|
import com.jd.lightapplication.service.SysUserService;
|
|
|
+import com.jd.lightapplication.utils.ValidateLoginAreaUtil;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
import lombok.Data;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.InitializingBean;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
|
|
+import org.springframework.data.geo.Distance;
|
|
|
+import org.springframework.data.geo.Point;
|
|
|
+import org.springframework.data.redis.connection.RedisGeoCommands;
|
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
|
import org.springframework.security.core.AuthenticationException;
|
|
|
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
|
@@ -34,6 +43,7 @@ import javax.servlet.ServletException;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
import java.io.IOException;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
@Data
|
|
|
@AllArgsConstructor
|
|
@@ -41,6 +51,9 @@ import java.io.IOException;
|
|
|
@Slf4j
|
|
|
public class MobileLoginFilter extends OncePerRequestFilter implements InitializingBean {
|
|
|
|
|
|
+ private ValidateLoginAreaUtil validateLoginAreaUtil;
|
|
|
+
|
|
|
+ private ConfigInfoService configInfoService;
|
|
|
private SysUserService sysUserService;
|
|
|
private SysRoleService sysRoleService;
|
|
|
private SysUserRoleService sysUserRoleService;
|
|
@@ -67,6 +80,9 @@ public class MobileLoginFilter extends OncePerRequestFilter implements Initializ
|
|
|
|
|
|
if (url.equals("/login/mobile") && request.getMethod().equals("POST")) {
|
|
|
try {
|
|
|
+ //验证地理位置
|
|
|
+ validateMap(request);
|
|
|
+ //验证手机号
|
|
|
validate(request);
|
|
|
} catch (AuthenticationException e) {
|
|
|
//验证出现异常,使用自定义的失败处理器来处理,并且直接return,不执行后面的过滤器
|
|
@@ -77,6 +93,68 @@ public class MobileLoginFilter extends OncePerRequestFilter implements Initializ
|
|
|
filterChain.doFilter(request, response);
|
|
|
}
|
|
|
|
|
|
+ private void validateMap(HttpServletRequest request) {
|
|
|
+ //获取手机号
|
|
|
+ String phone = request.getParameter("phone");
|
|
|
+ SysUser sysUser = sysUserService.getByPhone(phone);
|
|
|
+ //判断是不是来宾登录,判断条件:sysUser为空或者角色里面包括来宾
|
|
|
+ if (sysUser == null
|
|
|
+ || sysRoleService.list(
|
|
|
+ Wrappers.lambdaQuery(new SysRole())
|
|
|
+ .inSql(SysRole::getId, "SELECT role_id FROM sys_user_role WHERE user_id = " + sysUser.getId())
|
|
|
+ ).stream().filter(t -> {
|
|
|
+ return "GUEST".equals(t.getCode());
|
|
|
+ }).collect(Collectors.toList()).size() > 0) {
|
|
|
+ //表示是来宾登录,需要验证地理位置
|
|
|
+ Double longitude = Double.parseDouble(request.getParameter("longitude"));
|
|
|
+ Double latitude = Double.parseDouble(request.getParameter("latitude"));
|
|
|
+ log.info("获取到的经纬度【" + longitude + "," + latitude + "】");
|
|
|
+ //判断坐标是否符合登录条件
|
|
|
+ validateLoginAreaUtil.checkCoordinate(longitude, latitude);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断经坐标是否符合登录条件,这里使用Redis特殊数据类型来做
|
|
|
+ *
|
|
|
+ * @param longitude 经度
|
|
|
+ * @param latitude 纬度
|
|
|
+ */
|
|
|
+ /*private void checkCoordinate(Double longitude, Double latitude) {
|
|
|
+ //先获取系统配置里面的登录区域是否开启
|
|
|
+ ConfigInfo configInfo = configInfoService.findByKey("LOGIN_AREA_ISENABLE");
|
|
|
+ if (configInfo != null && "false".equals(configInfo.getConfigValue())) {
|
|
|
+ //未开启直接放行
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //查询经度、纬度、距离配置
|
|
|
+ String lgt = configInfoService.findByKey("LOGIN_AREA_LONGITUDE").getConfigValue(),
|
|
|
+ lat = configInfoService.findByKey("LOGIN_AREA_LATITUDE").getConfigValue(),
|
|
|
+ range = configInfoService.findByKey("LOGIN_AREA_RANGE").getConfigValue();
|
|
|
+ if (StrUtil.isBlank(lgt) || StrUtil.isBlank(lat) || StrUtil.isBlank(range)) {
|
|
|
+ throw new CaptchaException("系统配置异常,请联系管理员。");
|
|
|
+ }
|
|
|
+ Double lgtDouble;
|
|
|
+ Double latDouble;
|
|
|
+ Double rangeDouble;
|
|
|
+ try {
|
|
|
+ lgtDouble = Double.parseDouble(lgt);
|
|
|
+ latDouble = Double.parseDouble(lat);
|
|
|
+ rangeDouble = Double.parseDouble(range);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new CaptchaException("系统配置异常,请联系管理员。");
|
|
|
+ }
|
|
|
+ //判断坐标是否符合登录要求
|
|
|
+ redisTemplate.opsForGeo().add("geo", new Point(lgtDouble, latDouble), "basic");
|
|
|
+ redisTemplate.opsForGeo().add("geo", new Point(longitude, latitude), "user");
|
|
|
+
|
|
|
+ Distance rangeDistance = redisTemplate.opsForGeo().distance("geo", "basic", "user", RedisGeoCommands.DistanceUnit.METERS);
|
|
|
+ if (rangeDistance.getValue() >= rangeDouble) {
|
|
|
+ throw new CaptchaException("请在城管局范围内使用小程序");
|
|
|
+ }
|
|
|
+ }*/
|
|
|
+
|
|
|
/**
|
|
|
* 短信验证码的验证逻辑
|
|
|
*
|