diff --git a/src/main/java/com/gxwebsoft/common/core/security/JwtAuthenticationFilter.java b/src/main/java/com/gxwebsoft/common/core/security/JwtAuthenticationFilter.java index 1edca08..d545c25 100644 --- a/src/main/java/com/gxwebsoft/common/core/security/JwtAuthenticationFilter.java +++ b/src/main/java/com/gxwebsoft/common/core/security/JwtAuthenticationFilter.java @@ -4,6 +4,8 @@ import cn.hutool.core.util.StrUtil; import com.gxwebsoft.common.core.Constants; import com.gxwebsoft.common.core.config.ConfigProperties; 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.Menu; import com.gxwebsoft.common.system.entity.User; @@ -35,51 +37,63 @@ import java.util.stream.Collectors; */ @Component public class JwtAuthenticationFilter extends OncePerRequestFilter { - @Resource - private ConfigProperties configProperties; - @Resource - private UserService userService; - @Resource - private LoginRecordService loginRecordService; + @Resource + private ConfigProperties configProperties; + @Resource + private UserService userService; + @Resource + private LoginRecordService loginRecordService; + @Resource + private RedisUtil redisUtil; - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) - throws ServletException, IOException { - String access_token = JwtUtil.getAccessToken(request); - if (StrUtil.isNotBlank(access_token)) { - try { - // 解析token - Claims claims = JwtUtil.parseToken(access_token, configProperties.getTokenKey()); - JwtSubject jwtSubject = JwtUtil.getJwtSubject(claims); - User user = userService.getByUsername(jwtSubject.getUsername(), jwtSubject.getTenantId()); - if (user == null) { - throw new UsernameNotFoundException("Username not found"); - } - List authorities = user.getAuthorities().stream() - .filter(m -> StrUtil.isNotBlank(m.getAuthority())).collect(Collectors.toList()); - UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( - user, null, authorities); - SecurityContextHolder.getContext().setAuthentication(authentication); - // token将要过期签发新token, 防止突然退出登录 - long expiration = (claims.getExpiration().getTime() - new Date().getTime()) / 1000 / 60; - if (expiration < configProperties.getTokenRefreshTime()) { - String token = JwtUtil.buildToken(jwtSubject, configProperties.getTokenExpireTime(), - configProperties.getTokenKey()); - response.addHeader(Constants.TOKEN_HEADER_NAME, token); - loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_REFRESH, null, - user.getTenantId(), request); - } - } catch (ExpiredJwtException e) { - CommonUtil.responseError(response, Constants.TOKEN_EXPIRED_CODE, Constants.TOKEN_EXPIRED_MSG, - e.getMessage()); - return; - } catch (Exception e) { - CommonUtil.responseError(response, Constants.BAD_CREDENTIALS_CODE, Constants.BAD_CREDENTIALS_MSG, - e.toString()); - return; - } + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) + throws ServletException, IOException { + String access_token = JwtUtil.getAccessToken(request); + if (StrUtil.isNotBlank(access_token)) { + try { + // 解析token + Claims claims = JwtUtil.parseToken(access_token, configProperties.getTokenKey()); + JwtSubject jwtSubject = JwtUtil.getJwtSubject(claims); + + // 校验服务器白名单 + final SignCheckUtil checkUtil = new SignCheckUtil(); + String key = "WhiteDomain:" + jwtSubject.getTenantId(); + List whiteDomains = redisUtil.get(key, List.class); + if (!checkUtil.checkWhiteDomains(whiteDomains, request.getServerName())) { + throw new UsernameNotFoundException("The requested domain name is not on the whitelist"); } - chain.doFilter(request, response); + + User user = userService.getByUsername(jwtSubject.getUsername(), jwtSubject.getTenantId()); + if (user == null) { + throw new UsernameNotFoundException("Username not found"); + } + List authorities = user.getAuthorities().stream() + .filter(m -> StrUtil.isNotBlank(m.getAuthority())).collect(Collectors.toList()); + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( + user, null, authorities); + SecurityContextHolder.getContext().setAuthentication(authentication); + + // token将要过期签发新token, 防止突然退出登录 + long expiration = (claims.getExpiration().getTime() - new Date().getTime()) / 1000 / 60; + if (expiration < configProperties.getTokenRefreshTime()) { + String token = JwtUtil.buildToken(jwtSubject, configProperties.getTokenExpireTime(), + configProperties.getTokenKey()); + response.addHeader(Constants.TOKEN_HEADER_NAME, token); + loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_REFRESH, null, + user.getTenantId(), request); + } + } catch (ExpiredJwtException e) { + CommonUtil.responseError(response, Constants.TOKEN_EXPIRED_CODE, Constants.TOKEN_EXPIRED_MSG, + e.getMessage()); + return; + } catch (Exception e) { + CommonUtil.responseError(response, Constants.BAD_CREDENTIALS_CODE, Constants.BAD_CREDENTIALS_MSG, + e.toString()); + return; + } } + chain.doFilter(request, response); + } } diff --git a/src/main/java/com/gxwebsoft/common/core/utils/SignCheckUtil.java b/src/main/java/com/gxwebsoft/common/core/utils/SignCheckUtil.java index c260ae1..749d701 100644 --- a/src/main/java/com/gxwebsoft/common/core/utils/SignCheckUtil.java +++ b/src/main/java/com/gxwebsoft/common/core/utils/SignCheckUtil.java @@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject; import com.gxwebsoft.common.system.entity.KVEntity; import org.apache.commons.lang3.StringUtils; +import javax.annotation.Resource; import java.util.*; /** @@ -169,4 +170,24 @@ public class SignCheckUtil { return sign.equals(getWXSignString(params, key)); } + /** + * 白名单校验 + * @param domainName abc.com + * @return true + */ + public boolean checkWhiteDomains(List 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; + } + } diff --git a/src/main/java/com/gxwebsoft/common/core/web/BaseController.java b/src/main/java/com/gxwebsoft/common/core/web/BaseController.java index 4e9c3a5..ad91d42 100644 --- a/src/main/java/com/gxwebsoft/common/core/web/BaseController.java +++ b/src/main/java/com/gxwebsoft/common/core/web/BaseController.java @@ -32,8 +32,6 @@ public class BaseController { @Resource private HttpServletRequest request; @Resource - private StringRedisTemplate stringRedisTemplate; - @Resource private UserService userService; @Resource private CompanyService companyService; @@ -222,6 +220,8 @@ public class BaseController { return request.getParameter("sign"); } + + /** * 根据账号|手机号码|邮箱查找用户ID * diff --git a/src/main/java/com/gxwebsoft/common/system/controller/MainController.java b/src/main/java/com/gxwebsoft/common/system/controller/MainController.java index a0dce2d..b71f34c 100644 --- a/src/main/java/com/gxwebsoft/common/system/controller/MainController.java +++ b/src/main/java/com/gxwebsoft/common/system/controller/MainController.java @@ -23,6 +23,7 @@ import com.gxwebsoft.common.core.security.JwtUtil; import com.gxwebsoft.common.core.utils.CacheClient; 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.core.web.ApiResult; import com.gxwebsoft.common.core.web.BaseController; import com.gxwebsoft.common.core.web.ExistenceParam; @@ -39,20 +40,19 @@ import com.wf.captcha.SpecCaptcha; import io.jsonwebtoken.Claims; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import net.sf.jsqlparser.expression.LongValue; import org.springframework.scheduling.annotation.Async; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Random; +import java.util.*; import java.util.concurrent.TimeUnit; /** @@ -155,7 +155,7 @@ public class MainController extends BaseController { @ApiOperation("获取当前租户信息") @GetMapping("/auth/tenant") - public ApiResult tenant() { + public ApiResult tenant(HttpServletRequest request) { Integer tenantId = getTenantId(); if (tenantId == null) { return fail("缺少参数tenantId",null); @@ -167,7 +167,7 @@ public class MainController extends BaseController { // 企业信息 Company company = companyService.getByTenantIdRel(tenantId); if(company == null){ - return fail("该租户不存在或已过期",null); + return fail("该企业不存在!",null); } company.setBusinessEntity(null); company.setPhone(null); diff --git a/src/main/java/com/gxwebsoft/common/system/controller/WhiteDomainController.java b/src/main/java/com/gxwebsoft/common/system/controller/WhiteDomainController.java index 409d52d..7ee7f09 100644 --- a/src/main/java/com/gxwebsoft/common/system/controller/WhiteDomainController.java +++ b/src/main/java/com/gxwebsoft/common/system/controller/WhiteDomainController.java @@ -1,5 +1,7 @@ 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.system.entity.User; import com.gxwebsoft.common.system.service.WhiteDomainService; @@ -17,6 +19,7 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.List; +import java.util.stream.Collectors; /** * 服务器白名单控制器 @@ -26,10 +29,12 @@ import java.util.List; */ @Api(tags = "服务器白名单管理") @RestController -@RequestMapping("/api/common.system/white-domain") +@RequestMapping("/api/system/white-domain") public class WhiteDomainController extends BaseController { @Resource private WhiteDomainService whiteDomainService; + @Resource + private RedisUtil redisUtil; @PreAuthorize("hasAuthority('sys:whiteDomain:list')") @ApiOperation("分页查询服务器白名单") @@ -60,12 +65,18 @@ public class WhiteDomainController extends BaseController { @ApiOperation("添加服务器白名单") @PostMapping() public ApiResult save(@RequestBody WhiteDomain whiteDomain) { + String key = "WhiteDomain:"; // 记录当前登录用户id User loginUser = getLoginUser(); if (loginUser != null) { + key = key + loginUser.getTenantId(); whiteDomain.setUserId(loginUser.getUserId()); } if (whiteDomainService.save(whiteDomain)) { + // 重写缓存 + final List list = whiteDomainService.list(); + final List collect = list.stream().map(WhiteDomain::getDomain).collect(Collectors.toList()); + redisUtil.set(key,collect); return success("添加成功"); } return fail("添加失败"); @@ -88,6 +99,15 @@ public class WhiteDomainController extends BaseController { @DeleteMapping("/{id}") public ApiResult remove(@PathVariable("id") Integer id) { if (whiteDomainService.removeById(id)) { + // 重写缓存 + String key = "WhiteDomain:"; + User loginUser = getLoginUser(); + if (loginUser != null) { + key = key + loginUser.getTenantId(); + } + final List list = whiteDomainService.list(); + final List collect = list.stream().map(WhiteDomain::getDomain).collect(Collectors.toList()); + redisUtil.set(key,collect); return success("删除成功"); } return fail("删除失败");