From 34981c30a78e8bbd7791131059a9210f9928b62c Mon Sep 17 00:00:00 2001
From: 刘光辉 <347230014@qq.com>
Date: 星期四, 17 九月 2026 09:24:09 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master' into master
---
jnpf-gateway/src/main/java/jnpf/filter/MvcSecurityConfig.java | 149 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 149 insertions(+), 0 deletions(-)
diff --git a/jnpf-gateway/src/main/java/jnpf/filter/MvcSecurityConfig.java b/jnpf-gateway/src/main/java/jnpf/filter/MvcSecurityConfig.java
new file mode 100644
index 0000000..9933cf2
--- /dev/null
+++ b/jnpf-gateway/src/main/java/jnpf/filter/MvcSecurityConfig.java
@@ -0,0 +1,149 @@
+package jnpf.filter;
+
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.context.model.SaRequest;
+import cn.dev33.satoken.context.model.SaResponse;
+import cn.dev33.satoken.filter.SaFilterAuthStrategy;
+import cn.dev33.satoken.router.SaRouter;
+import jnpf.constant.GlobalConst;
+import jnpf.consts.AuthConsts;
+import jnpf.properties.MvcSecurityProperties;
+import jnpf.properties.SecurityProperties;
+import jnpf.util.Constants;
+import jnpf.util.ReactorUtil;
+import jnpf.util.UserProvider;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.reactive.CorsConfigurationSource;
+import org.springframework.web.cors.reactive.CorsWebFilter;
+import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
+
+import java.net.InetSocketAddress;
+import java.net.URI;
+
+/**
+ * mvc閰嶇疆
+ *
+ * @author JNPF寮�鍙戝钩鍙扮粍
+ * @version V5.0.0
+ * @copyright 寮曡繄淇℃伅鎶�鏈湁闄愬叕鍙革紙https://www.jnpfsoft.com锛�
+ * @date 2025-01-21
+ */
+@Slf4j
+@Configuration(proxyBeanMethods = false)
+public class MvcSecurityConfig {
+
+ private static final String DOMAIN_FORMAT = "%s://%s";
+ private static final String HOST_FORMAT = "%s:%s";
+
+ @Autowired
+ private MvcSecurityProperties mvcSecurityProperties;
+
+ @Autowired
+ private SecurityProperties securityProperties;
+
+ /**
+ * Header杩囨护鍣紝 涓鸿姹傛坊鍔� Id-Token
+ * @return
+ */
+ @Bean
+ public HttpHeadersFilter getMyHeadersFilter(){
+ return (input, exchange) -> {
+ if(securityProperties.isEnableInnerAuth() || securityProperties.isEnablePreAuth()){
+ input.add(AuthConsts.INNER_GATEWAY_TOKEN_KEY, UserProvider.getInnerAuthToken());
+ }
+ input.remove(GlobalConst.HEADER_HOST);
+ InetSocketAddress host = input.getHost();
+ if(host != null){
+ input.add(GlobalConst.HEADER_HOST, String.format(HOST_FORMAT, host.getHostString(), host.getPort()));
+ }
+
+ return input;
+ };
+ }
+
+ @Bean
+ public GlobalFilter getContextGatewayFilterForReactor(){
+ return new ContextGatewayFilterForReactor();
+ }
+
+
+ @Bean
+ public CorsWebFilter corsFilter() {
+ UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+ CorsConfiguration config = new CorsConfiguration();
+ // 鍏佽鍙戦�佸嚟鎹�
+ config.setAllowCredentials(true);
+ //鍏佽浠绘剰鍩熷悕璺ㄥ煙璁块棶鎺ュ彛
+ config.setAllowedOrigins(mvcSecurityProperties.getCors().getAllowedOrigins());
+ config.setAllowedOriginPatterns(mvcSecurityProperties.getCors().getAllowedOriginPatterns());
+ // 鍏佽鎵�鏈夊ご閮ㄤ俊鎭�
+ config.setAllowedHeaders(mvcSecurityProperties.getCors().getAllowedHeaders());
+ // 鍏佽鎵�鏈夎姹傛柟娉�
+ config.setAllowedMethods(mvcSecurityProperties.getCors().getAllowedMethods());
+ // 搴旂敤浜庢墍鏈夎矾寰�
+ source.registerCorsConfiguration("/**", config);
+ return new MyCorsFilter(source);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public SaFilterAuthStrategy defaultBeforeAuthStrategy() {
+ CorsConfiguration csrfConfiguration;
+ if(!mvcSecurityProperties.getCsrfOrigins().isEmpty() || !mvcSecurityProperties.getCsrfOriginsPatterns().isEmpty()) {
+ csrfConfiguration = new CorsConfiguration();
+ csrfConfiguration.setAllowedOrigins(mvcSecurityProperties.getCsrfOrigins());
+ csrfConfiguration.setAllowedOriginPatterns(mvcSecurityProperties.getCsrfOriginsPatterns());
+ } else {
+ csrfConfiguration = null;
+ }
+ return obj -> {
+ SaRequest request = SaHolder.getRequest();
+ // ---------- 璁剧疆璺ㄥ煙鍝嶅簲澶� ----------
+ SaResponse response = SaHolder.getResponse();
+ if(!ObjectUtils.isEmpty(mvcSecurityProperties.getHeaders().getServerName())){
+ response.setServer(mvcSecurityProperties.getHeaders().getServerName());
+ }
+ if(!ObjectUtils.isEmpty(mvcSecurityProperties.getHeaders().getXFrameOptions()) && !MvcSecurityProperties.XFrameOptionsMode.DISABLED.equals(mvcSecurityProperties.getHeaders().getXFrameOptions())){
+ response.setHeader(MvcSecurityProperties.HEADER_XFRAME_OPTIONS, mvcSecurityProperties.getHeaders().getXFrameOptions().getMode());
+ }
+ if(!ObjectUtils.isEmpty(mvcSecurityProperties.getHeaders().getXXssProtection()) && !MvcSecurityProperties.XXssProtectionMode.DISABLED.equals(mvcSecurityProperties.getHeaders().getXXssProtection())){
+ response.setHeader(MvcSecurityProperties.HEADER_XSS_PROTECTION, mvcSecurityProperties.getHeaders().getXXssProtection().getMode());
+ }
+ if(!ObjectUtils.isEmpty(mvcSecurityProperties.getHeaders().getXContentTypeOptions()) && !MvcSecurityProperties.XContentTypeOptions.DISABLED.equals(mvcSecurityProperties.getHeaders().getXContentTypeOptions())){
+ response.setHeader(MvcSecurityProperties.HEADER_CONTENT_TYPE_OPTIONS, mvcSecurityProperties.getHeaders().getXContentTypeOptions().getMode());
+ }
+
+ if(csrfConfiguration != null){
+ String referer = request.getHeader("referer");
+ if(!ObjectUtils.isEmpty(referer)) {
+ URI uri = URI.create(referer);
+ String refererDomain = String.format(DOMAIN_FORMAT, uri.getScheme(), uri.getAuthority());
+ String allowOrign = csrfConfiguration.checkOrigin(refererDomain);
+ if(ObjectUtils.isEmpty(allowOrign)){
+ log.error("Reject CSRF Request: {}, {}, {}, {}", request.getRequestPath(), referer, ReactorUtil.getIpAddr(request), request.getHeader(Constants.AUTHORIZATION));
+ response.setStatus(HttpStatus.FORBIDDEN.value());
+ SaRouter.back("Invalid CSRF Request");
+ }
+ }
+ }
+ };
+ }
+
+
+ @Order(-110)
+ public static class MyCorsFilter extends CorsWebFilter {
+ public MyCorsFilter(CorsConfigurationSource configSource) {
+ super(configSource);
+ }
+ }
+}
--
Gitblit v1.8.0