新增:服务器白名单校验功能

This commit is contained in:
gxwebsoft
2024-03-26 19:04:16 +08:00
parent 294306091a
commit 3b46e5ccc8
5 changed files with 107 additions and 52 deletions

View File

@@ -4,6 +4,8 @@ import cn.hutool.core.util.StrUtil;
import com.gxwebsoft.common.core.Constants; import com.gxwebsoft.common.core.Constants;
import com.gxwebsoft.common.core.config.ConfigProperties; import com.gxwebsoft.common.core.config.ConfigProperties;
import com.gxwebsoft.common.core.utils.CommonUtil; import com.gxwebsoft.common.core.utils.CommonUtil;
import com.gxwebsoft.common.core.utils.RedisUtil;
import com.gxwebsoft.common.core.utils.SignCheckUtil;
import com.gxwebsoft.common.system.entity.LoginRecord; import com.gxwebsoft.common.system.entity.LoginRecord;
import com.gxwebsoft.common.system.entity.Menu; import com.gxwebsoft.common.system.entity.Menu;
import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.common.system.entity.User;
@@ -41,6 +43,8 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
private UserService userService; private UserService userService;
@Resource @Resource
private LoginRecordService loginRecordService; private LoginRecordService loginRecordService;
@Resource
private RedisUtil redisUtil;
@Override @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
@@ -51,6 +55,15 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
// 解析token // 解析token
Claims claims = JwtUtil.parseToken(access_token, configProperties.getTokenKey()); Claims claims = JwtUtil.parseToken(access_token, configProperties.getTokenKey());
JwtSubject jwtSubject = JwtUtil.getJwtSubject(claims); JwtSubject jwtSubject = JwtUtil.getJwtSubject(claims);
// 校验服务器白名单
final SignCheckUtil checkUtil = new SignCheckUtil();
String key = "WhiteDomain:" + jwtSubject.getTenantId();
List<String> whiteDomains = redisUtil.get(key, List.class);
if (!checkUtil.checkWhiteDomains(whiteDomains, request.getServerName())) {
throw new UsernameNotFoundException("The requested domain name is not on the whitelist");
}
User user = userService.getByUsername(jwtSubject.getUsername(), jwtSubject.getTenantId()); User user = userService.getByUsername(jwtSubject.getUsername(), jwtSubject.getTenantId());
if (user == null) { if (user == null) {
throw new UsernameNotFoundException("Username not found"); throw new UsernameNotFoundException("Username not found");
@@ -60,6 +73,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
user, null, authorities); user, null, authorities);
SecurityContextHolder.getContext().setAuthentication(authentication); SecurityContextHolder.getContext().setAuthentication(authentication);
// token将要过期签发新token, 防止突然退出登录 // token将要过期签发新token, 防止突然退出登录
long expiration = (claims.getExpiration().getTime() - new Date().getTime()) / 1000 / 60; long expiration = (claims.getExpiration().getTime() - new Date().getTime()) / 1000 / 60;
if (expiration < configProperties.getTokenRefreshTime()) { if (expiration < configProperties.getTokenRefreshTime()) {

View File

@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
import com.gxwebsoft.common.system.entity.KVEntity; import com.gxwebsoft.common.system.entity.KVEntity;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import javax.annotation.Resource;
import java.util.*; import java.util.*;
/** /**
@@ -169,4 +170,24 @@ public class SignCheckUtil {
return sign.equals(getWXSignString(params, key)); return sign.equals(getWXSignString(params, key));
} }
/**
* 白名单校验
* @param domainName abc.com
* @return true
*/
public boolean checkWhiteDomains(List<String> whiteDomains, String domainName) {
if(whiteDomains == null){
return true;
}
if (whiteDomains.isEmpty()) {
return true;
}
for(String item: whiteDomains){
if(Objects.equals(item, domainName)){
return true;
}
}
return false;
}
} }

View File

@@ -32,8 +32,6 @@ public class BaseController {
@Resource @Resource
private HttpServletRequest request; private HttpServletRequest request;
@Resource @Resource
private StringRedisTemplate stringRedisTemplate;
@Resource
private UserService userService; private UserService userService;
@Resource @Resource
private CompanyService companyService; private CompanyService companyService;
@@ -222,6 +220,8 @@ public class BaseController {
return request.getParameter("sign"); return request.getParameter("sign");
} }
/** /**
* 根据账号|手机号码|邮箱查找用户ID * 根据账号|手机号码|邮箱查找用户ID
* *

View File

@@ -23,6 +23,7 @@ import com.gxwebsoft.common.core.security.JwtUtil;
import com.gxwebsoft.common.core.utils.CacheClient; import com.gxwebsoft.common.core.utils.CacheClient;
import com.gxwebsoft.common.core.utils.CommonUtil; import com.gxwebsoft.common.core.utils.CommonUtil;
import com.gxwebsoft.common.core.utils.RedisUtil; import com.gxwebsoft.common.core.utils.RedisUtil;
import com.gxwebsoft.common.core.utils.SignCheckUtil;
import com.gxwebsoft.common.core.web.ApiResult; import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController; import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.ExistenceParam; import com.gxwebsoft.common.core.web.ExistenceParam;
@@ -39,20 +40,19 @@ import com.wf.captcha.SpecCaptcha;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import net.sf.jsqlparser.expression.LongValue;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
@@ -155,7 +155,7 @@ public class MainController extends BaseController {
@ApiOperation("获取当前租户信息") @ApiOperation("获取当前租户信息")
@GetMapping("/auth/tenant") @GetMapping("/auth/tenant")
public ApiResult<?> tenant() { public ApiResult<?> tenant(HttpServletRequest request) {
Integer tenantId = getTenantId(); Integer tenantId = getTenantId();
if (tenantId == null) { if (tenantId == null) {
return fail("缺少参数tenantId",null); return fail("缺少参数tenantId",null);
@@ -167,7 +167,7 @@ public class MainController extends BaseController {
// 企业信息 // 企业信息
Company company = companyService.getByTenantIdRel(tenantId); Company company = companyService.getByTenantIdRel(tenantId);
if(company == null){ if(company == null){
return fail("租户不存在或已过期",null); return fail("企业不存在",null);
} }
company.setBusinessEntity(null); company.setBusinessEntity(null);
company.setPhone(null); company.setPhone(null);

View File

@@ -1,5 +1,7 @@
package com.gxwebsoft.common.system.controller; package com.gxwebsoft.common.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gxwebsoft.common.core.utils.RedisUtil;
import com.gxwebsoft.common.core.web.BaseController; import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.common.system.service.WhiteDomainService; import com.gxwebsoft.common.system.service.WhiteDomainService;
@@ -17,6 +19,7 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
* 服务器白名单控制器 * 服务器白名单控制器
@@ -26,10 +29,12 @@ import java.util.List;
*/ */
@Api(tags = "服务器白名单管理") @Api(tags = "服务器白名单管理")
@RestController @RestController
@RequestMapping("/api/common.system/white-domain") @RequestMapping("/api/system/white-domain")
public class WhiteDomainController extends BaseController { public class WhiteDomainController extends BaseController {
@Resource @Resource
private WhiteDomainService whiteDomainService; private WhiteDomainService whiteDomainService;
@Resource
private RedisUtil redisUtil;
@PreAuthorize("hasAuthority('sys:whiteDomain:list')") @PreAuthorize("hasAuthority('sys:whiteDomain:list')")
@ApiOperation("分页查询服务器白名单") @ApiOperation("分页查询服务器白名单")
@@ -60,12 +65,18 @@ public class WhiteDomainController extends BaseController {
@ApiOperation("添加服务器白名单") @ApiOperation("添加服务器白名单")
@PostMapping() @PostMapping()
public ApiResult<?> save(@RequestBody WhiteDomain whiteDomain) { public ApiResult<?> save(@RequestBody WhiteDomain whiteDomain) {
String key = "WhiteDomain:";
// 记录当前登录用户id // 记录当前登录用户id
User loginUser = getLoginUser(); User loginUser = getLoginUser();
if (loginUser != null) { if (loginUser != null) {
key = key + loginUser.getTenantId();
whiteDomain.setUserId(loginUser.getUserId()); whiteDomain.setUserId(loginUser.getUserId());
} }
if (whiteDomainService.save(whiteDomain)) { if (whiteDomainService.save(whiteDomain)) {
// 重写缓存
final List<WhiteDomain> list = whiteDomainService.list();
final List<String> collect = list.stream().map(WhiteDomain::getDomain).collect(Collectors.toList());
redisUtil.set(key,collect);
return success("添加成功"); return success("添加成功");
} }
return fail("添加失败"); return fail("添加失败");
@@ -88,6 +99,15 @@ public class WhiteDomainController extends BaseController {
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) { public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (whiteDomainService.removeById(id)) { if (whiteDomainService.removeById(id)) {
// 重写缓存
String key = "WhiteDomain:";
User loginUser = getLoginUser();
if (loginUser != null) {
key = key + loginUser.getTenantId();
}
final List<WhiteDomain> list = whiteDomainService.list();
final List<String> collect = list.stream().map(WhiteDomain::getDomain).collect(Collectors.toList());
redisUtil.set(key,collect);
return success("删除成功"); return success("删除成功");
} }
return fail("删除失败"); return fail("删除失败");