+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *
+ * http://www.gnu.org/licenses/lgpl.html + *
+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.continew.starter.security.limiter.annotation; + +import org.redisson.api.RateIntervalUnit; +import top.continew.starter.security.limiter.enums.LimitType; + +import java.lang.annotation.*; + +/** + * 限流注解 + * @author KAI + * @since 2.2.0 + */ +@Documented +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface RateLimiter { + + /** + * LimitType 限流模式 + * DEFAULT 全局限流 + * IP IP限流 + * CLUSTER 实例限流 + */ + LimitType limitType() default LimitType.DEFAULT; + + /** + * 缓存实例名称 + */ + String name() default ""; + + /** + * 限流key 支持 Spring EL 表达式 + */ + String key() default ""; + + /** + * 单位时间产生的令牌数 + */ + int rate() default Integer.MAX_VALUE; + + /** + * 限流时间 + */ + int rateInterval() default 0; + + /** + * 时间单位,默认毫秒 + */ + RateIntervalUnit timeUnit() default RateIntervalUnit.MILLISECONDS; + + /** + * 拒绝请求时的提示信息 + */ + String message() default "您操作过于频繁,请稍后再试!"; +} \ No newline at end of file diff --git a/continew-starter-security/continew-starter-security-limiter/src/main/java/top/continew/starter/security/limiter/annotation/RateLimiters.java b/continew-starter-security/continew-starter-security-limiter/src/main/java/top/continew/starter/security/limiter/annotation/RateLimiters.java new file mode 100644 index 00000000..b669e9bf --- /dev/null +++ b/continew-starter-security/continew-starter-security-limiter/src/main/java/top/continew/starter/security/limiter/annotation/RateLimiters.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *
+ * http://www.gnu.org/licenses/lgpl.html + *
+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.continew.starter.security.limiter.annotation; + +import java.lang.annotation.*; +/** + * 限流组 + * @author KAI + * @since 2.2.0 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface RateLimiters { + /** + * 用于管理多个 RateLimiter + */ + RateLimiter[] value(); +} diff --git a/continew-starter-security/continew-starter-security-limiter/src/main/java/top/continew/starter/security/limiter/aop/RateLimiterAspect.java b/continew-starter-security/continew-starter-security-limiter/src/main/java/top/continew/starter/security/limiter/aop/RateLimiterAspect.java new file mode 100644 index 00000000..aa9b87fc --- /dev/null +++ b/continew-starter-security/continew-starter-security-limiter/src/main/java/top/continew/starter/security/limiter/aop/RateLimiterAspect.java @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *
+ * http://www.gnu.org/licenses/lgpl.html + *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.continew.starter.security.limiter.aop;
+
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.extra.servlet.JakartaServletUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.redisson.api.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.expression.BeanFactoryResolver;
+import org.springframework.context.expression.MethodBasedEvaluationContext;
+import org.springframework.core.DefaultParameterNameDiscoverer;
+import org.springframework.core.ParameterNameDiscoverer;
+import org.springframework.expression.Expression;
+import org.springframework.expression.ExpressionParser;
+import org.springframework.expression.ParserContext;
+import org.springframework.expression.common.TemplateParserContext;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import top.continew.starter.security.limiter.annotation.RateLimiter;
+import top.continew.starter.security.limiter.annotation.RateLimiters;
+import top.continew.starter.security.limiter.autoconfigure.RateLimiterProperties;
+import top.continew.starter.security.limiter.enums.LimitType;
+import top.continew.starter.security.limiter.exception.RateLimiterException;
+import top.continew.starter.web.util.ServletUtils;
+
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 限流 AOP 拦截器
+ *
+ * @author KAI
+ * @since 2.2.0
+ */
+@Aspect
+@Component
+public class RateLimiterAspect {
+
+ private static final Logger log = LoggerFactory.getLogger(RateLimiterAspect.class);
+
+ private static final ConcurrentHashMap
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.continew.starter.security.limiter.autoconfigure;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import top.continew.starter.security.limiter.aop.RateLimiterAspect;
+
+/**
+ * 限流配置注入器
+ * @author KAI
+ * @since 2.2.0
+ */
+
+@AutoConfiguration
+@EnableConfigurationProperties(RateLimiterProperties.class)
+public class RateLimiterAutoConfiguration {
+
+ private static final Logger log = LoggerFactory.getLogger(RateLimiterAutoConfiguration.class);
+
+ @Bean
+ public RateLimiterAspect rateLimiterAspect() {
+ log.info("[ContiNew Starter] - Auto Configuration 'RateLimiterAspect' completed initialization.");
+ return new RateLimiterAspect();
+ }
+}
diff --git a/continew-starter-security/continew-starter-security-limiter/src/main/java/top/continew/starter/security/limiter/autoconfigure/RateLimiterProperties.java b/continew-starter-security/continew-starter-security-limiter/src/main/java/top/continew/starter/security/limiter/autoconfigure/RateLimiterProperties.java
new file mode 100644
index 00000000..7cdc059f
--- /dev/null
+++ b/continew-starter-security/continew-starter-security-limiter/src/main/java/top/continew/starter/security/limiter/autoconfigure/RateLimiterProperties.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.continew.starter.security.limiter.autoconfigure;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.util.StringUtils;
+
+/**
+ * 限流器配置属性
+ * @author KAI
+ * @since 2.2.0
+ */
+@ConfigurationProperties(prefix = "continew-starter.security.limiter")
+public class RateLimiterProperties {
+ private boolean enabled = false;
+
+ private String limiterKey = "RateLimiter:";
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public String getLimiterKey() {
+ return limiterKey;
+ }
+
+ public void setLimiterKey(String limiterKey) {
+ //不为空且不以":"结尾,则添加":"
+ if (StringUtils.hasText(limiterKey)) {
+ if (!limiterKey.endsWith(":")) {
+ limiterKey = limiterKey + ":";
+ }
+ }
+ this.limiterKey = limiterKey;
+ }
+
+}
diff --git a/continew-starter-security/continew-starter-security-limiter/src/main/java/top/continew/starter/security/limiter/enums/LimitType.java b/continew-starter-security/continew-starter-security-limiter/src/main/java/top/continew/starter/security/limiter/enums/LimitType.java
new file mode 100644
index 00000000..edfb65b6
--- /dev/null
+++ b/continew-starter-security/continew-starter-security-limiter/src/main/java/top/continew/starter/security/limiter/enums/LimitType.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.continew.starter.security.limiter.enums;
+
+/**
+ * 限流类型
+ * @author KAI
+ * @since 2.2.0
+ */
+public enum LimitType {
+
+ /**
+ * 全局限流
+ */
+ DEFAULT,
+ /**
+ * 根据IP限流
+ */
+ IP,
+ /**
+ * 根据实例限流(支持集群多实例)
+ */
+ CLUSTER
+}
diff --git a/continew-starter-security/continew-starter-security-limiter/src/main/java/top/continew/starter/security/limiter/exception/RateLimiterException.java b/continew-starter-security/continew-starter-security-limiter/src/main/java/top/continew/starter/security/limiter/exception/RateLimiterException.java
new file mode 100644
index 00000000..20331b2a
--- /dev/null
+++ b/continew-starter-security/continew-starter-security-limiter/src/main/java/top/continew/starter/security/limiter/exception/RateLimiterException.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.continew.starter.security.limiter.exception;
+
+import top.continew.starter.core.exception.BaseException;
+
+/**
+ * 限流异常
+ * @author KAI
+ * @since 2.2.0
+ */
+public class RateLimiterException extends BaseException {
+ public RateLimiterException(String message) {
+ super(message);
+ }
+}
diff --git a/continew-starter-security/continew-starter-security-limiter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/continew-starter-security/continew-starter-security-limiter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 00000000..d365e008
--- /dev/null
+++ b/continew-starter-security/continew-starter-security-limiter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1 @@
+top.continew.starter.security.limiter.autoconfigure.RateLimiterAutoConfiguration
\ No newline at end of file
diff --git a/continew-starter-security/continew-starter-security-limiter/src/main/resources/spel-extension.json b/continew-starter-security/continew-starter-security-limiter/src/main/resources/spel-extension.json
new file mode 100644
index 00000000..9088db73
--- /dev/null
+++ b/continew-starter-security/continew-starter-security-limiter/src/main/resources/spel-extension.json
@@ -0,0 +1,7 @@
+{
+ "top.continew.starter.security.limiter.annotation.RateLimiter@key":{
+ "method":{
+ "parameters": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/continew-starter-security/pom.xml b/continew-starter-security/pom.xml
index dd87ac2f..84df7437 100644
--- a/continew-starter-security/pom.xml
+++ b/continew-starter-security/pom.xml
@@ -17,6 +17,7 @@