From 79fbd51fca1e49db2a15347c704e991412eb8e68 Mon Sep 17 00:00:00 2001 From: tangwei Date: Tue, 9 Jun 2026 16:30:14 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=A2=9E=E5=8A=A0=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=E4=B8=8B=E6=8B=89=E9=89=B4=E6=9D=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/RegisterAccessTokenFilter.java | 69 ++++++++++++++ .../yfd/platform/config/SecurityConfig.java | 5 ++ .../RegisterDropdownController.java | 53 +++++++++++ .../controller/RegisterAccessController.java | 26 ++++++ .../service/RegisterAccessTokenService.java | 89 +++++++++++++++++++ backend/src/main/resources/application.yml | 2 +- 6 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/java/com/yfd/platform/config/RegisterAccessTokenFilter.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_base/controller/RegisterDropdownController.java create mode 100644 backend/src/main/java/com/yfd/platform/system/controller/RegisterAccessController.java create mode 100644 backend/src/main/java/com/yfd/platform/system/service/RegisterAccessTokenService.java diff --git a/backend/src/main/java/com/yfd/platform/config/RegisterAccessTokenFilter.java b/backend/src/main/java/com/yfd/platform/config/RegisterAccessTokenFilter.java new file mode 100644 index 00000000..024e4967 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/config/RegisterAccessTokenFilter.java @@ -0,0 +1,69 @@ +package com.yfd.platform.config; + +import com.yfd.platform.system.service.RegisterAccessTokenService; +import jakarta.annotation.Resource; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +@Component +public class RegisterAccessTokenFilter extends OncePerRequestFilter { + + private static final String ENG_INFO_PATH = "/register/dropdown/engInfo"; + private static final String HBRV_PATH = "/register/dropdown/hbrv"; + private static final String HYCD_PATH = "/register/dropdown/hycd"; + + @Resource + private RegisterAccessTokenService registerAccessTokenService; + + @Override + protected void doFilterInternal(HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + String requestPath = resolveRequestPath(request); + if (!needsRegisterAccessToken(requestPath)) { + filterChain.doFilter(request, response); + return; + } + + String token = registerAccessTokenService.resolveToken(request); + if (!registerAccessTokenService.validateToken(token, request)) { + response.sendError(HttpServletResponse.SC_FORBIDDEN, "registerToken无效或已过期"); + return; + } + + UsernamePasswordAuthenticationToken authenticationToken = + new UsernamePasswordAuthenticationToken( + "register-access", + null, + AuthorityUtils.NO_AUTHORITIES + ); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + filterChain.doFilter(request, response); + } + + private boolean needsRegisterAccessToken(String uri) { + return ENG_INFO_PATH.equals(uri) || HBRV_PATH.equals(uri) || HYCD_PATH.equals(uri); + } + + private String resolveRequestPath(HttpServletRequest request) { + String servletPath = request.getServletPath(); + if (servletPath != null && !servletPath.isEmpty()) { + return servletPath; + } + String uri = request.getRequestURI(); + String contextPath = request.getContextPath(); + if (contextPath != null && !contextPath.isEmpty() && uri.startsWith(contextPath)) { + return uri.substring(contextPath.length()); + } + return uri; + } +} diff --git a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java index 3aa9f789..79a4e331 100644 --- a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java @@ -39,6 +39,9 @@ public class SecurityConfig { @Autowired private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter; + @Autowired + private RegisterAccessTokenFilter registerAccessTokenFilter; + @Autowired private AuthenticationException authenticationException; @@ -57,6 +60,7 @@ public class SecurityConfig { .requestMatchers("/data/fishDraft/previewFile").permitAll() .requestMatchers("/tempFile/**").permitAll() .requestMatchers("/system/user/auditUser").permitAll() + .requestMatchers("/register/accessToken").permitAll() // .requestMatchers("/eng/**").permitAll() // .requestMatchers("/eq/**").permitAll() // .requestMatchers("/env/**").permitAll() @@ -93,6 +97,7 @@ public class SecurityConfig { ) .cors(cors -> {}); + http.addFilterBefore(registerAccessTokenFilter, UsernamePasswordAuthenticationFilter.class); http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); http.exceptionHandling(ex -> ex diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/controller/RegisterDropdownController.java b/backend/src/main/java/com/yfd/platform/qgc_base/controller/RegisterDropdownController.java new file mode 100644 index 00000000..e79db19b --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_base/controller/RegisterDropdownController.java @@ -0,0 +1,53 @@ +package com.yfd.platform.qgc_base.controller; + +import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.qgc_base.domain.SdEngInfoBHRequest; +import com.yfd.platform.qgc_base.service.ISdEngInfoBHService; +import com.yfd.platform.qgc_base.service.ISdHbrvDicService; +import com.yfd.platform.qgc_base.service.ISdHycdDicService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/register/dropdown") +@Tag(name = "注册下拉数据") +public class RegisterDropdownController { + + @Resource + private ISdEngInfoBHService engInfoBHService; + + @Resource + private ISdHbrvDicService hbrvDicService; + + @Resource + private ISdHycdDicService hycdDicService; + + @PostMapping("/engInfo") + @Operation(summary = "注册场景电站下拉") + public ResponseResult engInfoDropdown(@RequestBody SdEngInfoBHRequest request) { + return ResponseResult.successData(engInfoBHService.selectRegDropdown(request)); + } + + @GetMapping("/hbrv") + @Operation(summary = "注册场景基地流域下拉") + public ResponseResult hbrvDropdown(@RequestParam(required = false) String hbrvnm, + @RequestParam(required = false) String baseid) { + return ResponseResult.successData(hbrvDicService.regDropdown(hbrvnm, baseid)); + } + + @GetMapping("/hycd") + @Operation(summary = "注册场景公司下拉") + public ResponseResult hycdDropdown(@RequestParam(required = false) String hynm, + @RequestParam(required = false) Integer grd, + @RequestParam(required = false) Integer lx, + @RequestParam(required = false) String phycd) { + return ResponseResult.successData(hycdDicService.regDropdown(hynm, grd, lx, phycd)); + } +} diff --git a/backend/src/main/java/com/yfd/platform/system/controller/RegisterAccessController.java b/backend/src/main/java/com/yfd/platform/system/controller/RegisterAccessController.java new file mode 100644 index 00000000..83a01fcf --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/system/controller/RegisterAccessController.java @@ -0,0 +1,26 @@ +package com.yfd.platform.system.controller; + +import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.system.service.RegisterAccessTokenService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/register") +@Tag(name = "注册访问控制") +public class RegisterAccessController { + + @Resource + private RegisterAccessTokenService registerAccessTokenService; + + @GetMapping("/accessToken") + @Operation(summary = "获取注册场景临时访问令牌") + public ResponseResult getRegisterAccessToken(HttpServletRequest request) { + return ResponseResult.successData(registerAccessTokenService.createToken(request)); + } +} diff --git a/backend/src/main/java/com/yfd/platform/system/service/RegisterAccessTokenService.java b/backend/src/main/java/com/yfd/platform/system/service/RegisterAccessTokenService.java new file mode 100644 index 00000000..eae95315 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/system/service/RegisterAccessTokenService.java @@ -0,0 +1,89 @@ +package com.yfd.platform.system.service; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.yfd.platform.config.WebConfig; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +@Service +public class RegisterAccessTokenService { + + public static final String TOKEN_HEADER = "register-token"; + public static final String TOKEN_PARAM = "registerToken"; + public static final long EXPIRE_MILLIS = 5 * 60 * 1000L; + private static final String CACHE_PREFIX = "register:access:"; + + @Resource + private WebConfig webConfig; + + public Map createToken(HttpServletRequest request) { + String token = UUID.randomUUID().toString().replace("-", ""); + long expireAt = System.currentTimeMillis() + EXPIRE_MILLIS; + + Map payload = new HashMap<>(); + payload.put("ip", getClientIp(request)); + payload.put("userAgent", getUserAgent(request)); + payload.put("expireAt", expireAt); + + webConfig.loginuserCache().put(CACHE_PREFIX + token, JSON.toJSONString(payload), EXPIRE_MILLIS); + + Map result = new HashMap<>(); + result.put("registerToken", token); + result.put("headerName", TOKEN_HEADER); + result.put("expireIn", EXPIRE_MILLIS / 1000); + result.put("expireAt", expireAt); + return result; + } + + public boolean validateToken(String token, HttpServletRequest request) { + if (StrUtil.isBlank(token)) { + return false; + } + String cacheValue = webConfig.loginuserCache().get(CACHE_PREFIX + token); + if (StrUtil.isBlank(cacheValue)) { + return false; + } + JSONObject payload = JSON.parseObject(cacheValue); + if (payload == null) { + return false; + } + Long expireAt = payload.getLong("expireAt"); + if (expireAt == null || expireAt < System.currentTimeMillis()) { + webConfig.loginuserCache().remove(CACHE_PREFIX + token); + return false; + } + String ip = payload.getString("ip"); + String userAgent = payload.getString("userAgent"); + String clientIp = getClientIp(request); + String userAgent1 = getUserAgent(request); + return StrUtil.equals(ip,clientIp ) + && StrUtil.equals(userAgent, userAgent1); + } + + public String resolveToken(HttpServletRequest request) { + String token = request.getHeader(TOKEN_HEADER); + if (StrUtil.isBlank(token)) { + token = request.getParameter(TOKEN_PARAM); + } + return token; + } + + private String getClientIp(HttpServletRequest request) { + String ip = request.getHeader("X-Forwarded-For"); + if (StrUtil.isNotBlank(ip)) { + return ip.split(",")[0].trim(); + } + return request.getRemoteAddr(); + } + + private String getUserAgent(HttpServletRequest request) { + return StrUtil.nullToDefault(request.getHeader("User-Agent"), ""); + } +} diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 03a78ea5..cd6f706e 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -1,6 +1,6 @@ spring: profiles: - active: devtw + active: prod jasypt: encryptor: