diff --git a/.workflow/branch-pipeline.yml b/.workflow/branch-pipeline.yml new file mode 100644 index 0000000000000000000000000000000000000000..9d2a2926f31b55f68083a3cb58c4cb6d6f43a07f --- /dev/null +++ b/.workflow/branch-pipeline.yml @@ -0,0 +1,53 @@ +version: '1.0' +name: branch-pipeline +displayName: BranchPipeline +stages: + - stage: + name: compile + displayName: 编译 + steps: + - step: build@maven + name: build_maven + displayName: Maven 构建 + # 支持6、7、8、9、10、11六个版本 + jdkVersion: 8 + # 支持2.2.1、3.2.5、3.3.9、3.5.2、3.5.3、3.5.4、3.6.1、3.6.3八个版本 + mavenVersion: 3.3.9 + # 构建命令 + commands: + - mvn -B clean package -Dmaven.test.skip=true + # 非必填字段,开启后表示将构建产物暂存,但不会上传到制品库中,7天后自动清除 + artifacts: + # 构建产物名字,作为产物的唯一标识可向下传递,支持自定义,默认为BUILD_ARTIFACT。在下游可以通过${BUILD_ARTIFACT}方式引用来获取构建物地址 + - name: BUILD_ARTIFACT + # 构建产物获取路径,是指代码编译完毕之后构建物的所在路径,如通常jar包在target目录下。当前目录为代码库根目录 + path: + - ./target + - step: publish@general_artifacts + name: publish_general_artifacts + displayName: 上传制品 + # 上游构建任务定义的产物名,默认BUILD_ARTIFACT + dependArtifact: BUILD_ARTIFACT + # 上传到制品库时的制品命名,默认output + artifactName: output + dependsOn: build_maven + - stage: + name: release + displayName: 发布 + steps: + - step: publish@release_artifacts + name: publish_release_artifacts + displayName: '发布' + # 上游上传制品任务的产出 + dependArtifact: output + # 发布制品版本号 + version: '1.0.0.0' + # 是否开启版本号自增,默认开启 + autoIncrement: true +triggers: + push: + branches: + exclude: + - master + include: + - .* diff --git a/.workflow/master-pipeline.yml b/.workflow/master-pipeline.yml new file mode 100644 index 0000000000000000000000000000000000000000..5d926c26f79e41d10427f87bf003ef99fe2fbd79 --- /dev/null +++ b/.workflow/master-pipeline.yml @@ -0,0 +1,51 @@ +version: '1.0' +name: master-pipeline +displayName: MasterPipeline +stages: + - stage: + name: compile + displayName: 编译 + steps: + - step: build@maven + name: build_maven + displayName: Maven 构建 + # 支持6、7、8、9、10、11六个版本 + jdkVersion: 8 + # 支持2.2.1、3.2.5、3.3.9、3.5.2、3.5.3、3.5.4、3.6.1、3.6.3八个版本 + mavenVersion: 3.3.9 + # 构建命令 + commands: + - mvn -B clean package -Dmaven.test.skip=true + # 非必填字段,开启后表示将构建产物暂存,但不会上传到制品库中,7天后自动清除 + artifacts: + # 构建产物名字,作为产物的唯一标识可向下传递,支持自定义,默认为BUILD_ARTIFACT。在下游可以通过${BUILD_ARTIFACT}方式引用来获取构建物地址 + - name: BUILD_ARTIFACT + # 构建产物获取路径,是指代码编译完毕之后构建物的所在路径,如通常jar包在target目录下。当前目录为代码库根目录 + path: + - ./target + - step: publish@general_artifacts + name: publish_general_artifacts + displayName: 上传制品 + # 上游构建任务定义的产物名,默认BUILD_ARTIFACT + dependArtifact: BUILD_ARTIFACT + # 上传到制品库时的制品命名,默认output + artifactName: output + dependsOn: build_maven + - stage: + name: release + displayName: 发布 + steps: + - step: publish@release_artifacts + name: publish_release_artifacts + displayName: '发布' + # 上游上传制品任务的产出 + dependArtifact: output + # 发布制品版本号 + version: '1.0.0.0' + # 是否开启版本号自增,默认开启 + autoIncrement: true +triggers: + push: + branches: + include: + - master diff --git a/.workflow/pr-pipeline.yml b/.workflow/pr-pipeline.yml new file mode 100644 index 0000000000000000000000000000000000000000..3f7579dd405c85f97f77df0357ec4893e616f85f --- /dev/null +++ b/.workflow/pr-pipeline.yml @@ -0,0 +1,40 @@ +version: '1.0' +name: pr-pipeline +displayName: PRPipeline +stages: + - stage: + name: compile + displayName: 编译 + steps: + - step: build@maven + name: build_maven + displayName: Maven 构建 + # 支持6、7、8、9、10、11六个版本 + jdkVersion: 8 + # 支持2.2.1、3.2.5、3.3.9、3.5.2、3.5.3、3.5.4、3.6.1、3.6.3八个版本 + mavenVersion: 3.3.9 + # 构建命令 + commands: + - mvn -B clean package -Dmaven.test.skip=true + # 非必填字段,开启后表示将构建产物暂存,但不会上传到制品库中,7天后自动清除 + artifacts: + # 构建产物名字,作为产物的唯一标识可向下传递,支持自定义,默认为BUILD_ARTIFACT。在下游可以通过${BUILD_ARTIFACT}方式引用来获取构建物地址 + - name: BUILD_ARTIFACT + # 构建产物获取路径,是指代码编译完毕之后构建物的所在路径,如通常jar包在target目录下。当前目录为代码库根目录 + path: + - ./target + - step: publish@general_artifacts + name: publish_general_artifacts + displayName: 上传制品 + # 上游构建任务定义的产物名,默认BUILD_ARTIFACT + dependArtifact: BUILD_ARTIFACT + # 构建产物制品库,默认default,系统默认创建 + artifactRepository: default + # 上传到制品库时的制品命名,默认output + artifactName: output + dependsOn: build_maven +triggers: + pr: + branches: + include: + - master diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000000000000000000000000000000000000..122583568c41a7f19309eeddb9ebe07caf7d3eb2 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,22 @@ +# 这是一个注释。 +# 指定根目录下README文件的Code Owner +# commiter 非项目成员 维护者 维护者 开发者 +README.md @duxin @stars @yinlin @yanfan @gitcode_test + +# 指定scripts文件夹的Code Owner gitee规则 +scripts/* @yinlin + +# 指定scripts文件夹的Code Owner github规则 +/scripts/* @jiulongSQ + +# 指定scripts文件夹的Code Owner,不一定是根目录 gitee规则 +scripts/ @aron1 + +# 指定scripts文件夹的Code Owner,不一定是根目录 github规则 +/scripts/ @yanfan + +# 指定所有JS文件的Code Owner +*.js @stars + +# 指定docs文件夹的多个Code Owners +/docs/ @username1 @username2 \ No newline at end of file diff --git a/README.md b/README.md index f67bf8741418543afd4b2ff54463470b117559f5..406c22480f66e9e2b61b9d624dab63bd99c8b63b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ +
哈哈哈
-
参数 [SaCheckOr 注解的实例] - * - * @param checkOrAnnotation / - * @return / - */ - public SaStrategy setCheckOrAnnotation(SaCheckOrAnnotationFunction checkOrAnnotation) { - this.checkOrAnnotation = checkOrAnnotation; - return this; - } - - /** - * 从元素上获取注解 - * - * @param getAnnotation / - * @return / - */ - public SaStrategy setGetAnnotation(SaGetAnnotationFunction getAnnotation) { - this.getAnnotation = getAnnotation; - return this; - } - - /** - * 判断一个 Method 或其所属 Class 是否包含指定注解 - * - * @param isAnnotationPresent / - * @return / - */ - public SaStrategy setIsAnnotationPresent(SaIsAnnotationPresentFunction isAnnotationPresent) { - this.isAnnotationPresent = isAnnotationPresent; - return this; - } - /** * 生成唯一式 token 的算法 * diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaFoxUtil.java b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaFoxUtil.java index a28a1072c2eab3528c56e3dd6310b25ffaa03b42..63bfbb60808b97639b7f062db6a7b1c0972d4a9c 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaFoxUtil.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaFoxUtil.java @@ -29,7 +29,6 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.ThreadLocalRandom; -import java.util.regex.Pattern; /** * Sa-Token 内部工具类 @@ -76,6 +75,17 @@ public class SaFoxUtil { return sb.toString(); } + /** + * 生成指定区间的 int 值 + * + * @param min 最小值(包括) + * @param max 最大值(包括) + * @return / + */ + public static int getRandomNumber(int min, int max) { + return ThreadLocalRandom.current().nextInt(min, max + 1); + } + /** * 指定元素是否为null或者空字符串 * @param str 指定元素 @@ -96,14 +106,35 @@ public class SaFoxUtil { /** * 指定数组是否为null或者空数组 + *
可标注在函数、类上(效果等同于标注在此类的所有方法上) + * + * @author click33 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD, ElementType.TYPE}) +public @interface SaUserCheckLogin { + +} diff --git a/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/custom_annotation/SaUserCheckPermission.java b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/custom_annotation/SaUserCheckPermission.java new file mode 100644 index 0000000000000000000000000000000000000000..eb980411c938abe0d9488801a88dfb003324cb3e --- /dev/null +++ b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/custom_annotation/SaUserCheckPermission.java @@ -0,0 +1,50 @@ +package com.pj.satoken.custom_annotation; + +import cn.dev33.satoken.annotation.SaMode; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 权限认证(User版):必须具有指定权限才能进入该方法 + *
可标注在函数、类上(效果等同于标注在此类的所有方法上) + * + * @author click33 + * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD, ElementType.TYPE}) +public @interface SaUserCheckPermission { + + /** + * 需要校验的权限码 + * @return 需要校验的权限码 + */ + String [] value() default {}; + + /** + * 验证模式:AND | OR,默认AND + * @return 验证模式 + */ + SaMode mode() default SaMode.AND; + + /** + * 在权限校验不通过时的次要选择,两者只要其一校验成功即可通过校验 + * + *
+ * 例1:@SaCheckPermission(value="user-add", orRole="admin"), + * 代表本次请求只要具有 user-add权限 或 admin角色 其一即可通过校验。 + *
+ * + *
+ * 例2: orRole = {"admin", "manager", "staff"},具有三个角色其一即可。
+ * 例3: orRole = {"admin, manager, staff"},必须三个角色同时具备。
+ *
可标注在函数、类上(效果等同于标注在此类的所有方法上) + * @author click33 + * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD, ElementType.TYPE}) +public @interface SaUserCheckRole { + + /** + * 需要校验的角色标识 + * @return 需要校验的角色标识 + */ + String [] value() default {}; + + /** + * 验证模式:AND | OR,默认AND + * @return 验证模式 + */ + SaMode mode() default SaMode.AND; + +} diff --git a/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/custom_annotation/SaUserCheckSafe.java b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/custom_annotation/SaUserCheckSafe.java new file mode 100644 index 0000000000000000000000000000000000000000..49e2da67e3999a779f0bdbfe1df10084c7446119 --- /dev/null +++ b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/custom_annotation/SaUserCheckSafe.java @@ -0,0 +1,28 @@ +package com.pj.satoken.custom_annotation; + +import cn.dev33.satoken.util.SaTokenConsts; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 二级认证校验(User版):客户端必须完成二级认证之后,才能进入该方法,否则将被抛出异常。 + * + *
可标注在方法、类上(效果等同于标注在此类的所有方法上)。
+ *
+ * @author click33
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.METHOD, ElementType.TYPE })
+public @interface SaUserCheckSafe {
+
+ /**
+ * 要校验的服务
+ *
+ * @return /
+ */
+ String value() default SaTokenConsts.DEFAULT_SAFE_AUTH_SERVICE;
+
+}
diff --git a/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/custom_annotation/handler/CheckAccountHandler.java b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/custom_annotation/handler/CheckAccountHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..2b49badff844e99dd9be577d52f756e8d5d86323
--- /dev/null
+++ b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/custom_annotation/handler/CheckAccountHandler.java
@@ -0,0 +1,42 @@
+package com.pj.satoken.custom_annotation.handler;
+
+import cn.dev33.satoken.annotation.handler.SaAnnotationHandlerInterface;
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.exception.SaTokenException;
+import com.pj.satoken.custom_annotation.CheckAccount;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.Method;
+
+/**
+ * 注解 CheckAccount 的处理器
+ *
+ * @author click33
+ *
+ */
+@Component
+public class CheckAccountHandler implements SaAnnotationHandlerInterface 可标注在函数、类上(效果等同于标注在此类的所有方法上)
diff --git a/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/at/SaUserCheckPermission.java b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/merge_annotation/SaUserCheckPermission.java
similarity index 62%
rename from sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/at/SaUserCheckPermission.java
rename to sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/merge_annotation/SaUserCheckPermission.java
index 22938622f170aabf4faeaa5446664889186d2f63..641f23c6e2178e10d0e88397a7730a7f7ecbb929 100644
--- a/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/at/SaUserCheckPermission.java
+++ b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/merge_annotation/SaUserCheckPermission.java
@@ -1,16 +1,15 @@
-package com.pj.satoken.at;
+package com.pj.satoken.merge_annotation;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.dev33.satoken.annotation.SaMode;
+import com.pj.satoken.StpUserUtil;
+import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-import com.pj.satoken.StpUserUtil;
-import org.springframework.core.annotation.AliasFor;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.dev33.satoken.annotation.SaMode;
-
/**
* 权限认证(User版):必须具有指定权限才能进入该方法
* 可标注在函数、类上(效果等同于标注在此类的所有方法上)
@@ -35,5 +34,23 @@ public @interface SaUserCheckPermission {
*/
@AliasFor(annotation = SaCheckPermission.class)
SaMode mode() default SaMode.AND;
-
+
+ /**
+ * 在权限校验不通过时的次要选择,两者只要其一校验成功即可通过校验
+ *
+ *
+ * 例1:@SaCheckPermission(value="user-add", orRole="admin"),
+ * 代表本次请求只要具有 user-add权限 或 admin角色 其一即可通过校验。
+ *
+ * 例2: orRole = {"admin", "manager", "staff"},具有三个角色其一即可。 可标注在函数、类上(效果等同于标注在此类的所有方法上)
diff --git a/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/merge_annotation/SaUserCheckSafe.java b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/merge_annotation/SaUserCheckSafe.java
new file mode 100644
index 0000000000000000000000000000000000000000..60bd4e56ea768856a29de57beff813db12fd3560
--- /dev/null
+++ b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/merge_annotation/SaUserCheckSafe.java
@@ -0,0 +1,31 @@
+package com.pj.satoken.merge_annotation;
+
+import cn.dev33.satoken.annotation.SaCheckSafe;
+import cn.dev33.satoken.util.SaTokenConsts;
+import com.pj.satoken.StpUserUtil;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 二级认证校验(User版):客户端必须完成二级认证之后,才能进入该方法,否则将被抛出异常。
+ *
+ * 可标注在方法、类上(效果等同于标注在此类的所有方法上)。
+ *
+ * @author click33
+ */
+@SaCheckSafe(type = StpUserUtil.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.METHOD, ElementType.TYPE })
+public @interface SaUserCheckSafe {
+
+ /**
+ * 要校验的服务
+ *
+ * @return /
+ */
+ String value() default SaTokenConsts.DEFAULT_SAFE_AUTH_SERVICE;
+
+}
diff --git a/sa-token-demo/sa-token-demo-dubbo/sa-token-demo-dubbo-consumer/pom.xml b/sa-token-demo/sa-token-demo-dubbo/sa-token-demo-dubbo-consumer/pom.xml
index fcfdc51de9b34a56dba92b367aa09ec03e05d3df..5954ce96123a16dcdc189935674b2b9d3af41465 100644
--- a/sa-token-demo/sa-token-demo-dubbo/sa-token-demo-dubbo-consumer/pom.xml
+++ b/sa-token-demo/sa-token-demo-dubbo/sa-token-demo-dubbo-consumer/pom.xml
@@ -17,7 +17,7 @@
+ * 例3: orRole = {"admin, manager, staff"},必须三个角色同时具备。
+ *
授权码:OAuth2.0标准授权流程,先 (重定向) 获取Code授权码,再 (Rest API) 获取 Access-Token 和 Openid
- + - 当请求链接不包含scope权限时,将无需用户手动确认,做到静默授权,当然此时我们也只能获取openid -http://sa-oauth-server.com:8001/oauth2/authorize?response_type=code&client_id=1001&redirect_uri=http://sa-oauth-client.com:8002/
+ 当请求链接不包含 scope 权限,或请求的 scope 近期已授权时,将无需用户手动确认,做到静默授权
+ http://sa-oauth-server.com:8000/oauth2/authorize?response_type=code&client_id=1001&redirect_uri=http://sa-oauth-client.com:8002/
-
+
- 当请求链接包含具体的scope权限时,将需要用户手动确认,此时我们除了openid以外还可以获取更多的资源
- http://sa-oauth-server.com:8001/oauth2/authorize?response_type=code&client_id=1001&redirect_uri=http://sa-oauth-client.com:8002/&scope=userinfo
+ 当请求链接包含具体的 scope 权限时,将需要用户手动确认,此时 OAuth-Server 会返回更多的数据
+ http://sa-oauth-server.com:8000/oauth2/authorize?response_type=code&client_id=1001&redirect_uri=http://sa-oauth-client.com:8002/&scope=openid,userinfo
我们可以拿着 Refresh-Token 去刷新我们的 Access-Token,每次刷新后旧Token将作废
- http://sa-oauth-server.com:8001/oauth2/refresh?grant_type=refresh_token&client_id={value}&client_secret={value}&refresh_token={value}
+ http://sa-oauth-server.com:8000/oauth2/refresh?grant_type=refresh_token&client_id={value}&client_secret={value}&refresh_token={value}
使用 Access-Token 置换资源: 获取账号昵称、头像、性别等信息 (Access-Token具备userinfo权限时才可以获取成功)
- http://sa-oauth-server.com:8001/oauth2/userinfo?access_token={value}
+ http://sa-oauth-server.com:8000/oauth2/userinfo?access_token={value}
http://sa-oauth-server.com:8001/oauth2/authorize?response_type=token&client_id=1001&redirect_uri=http://sa-oauth-client.com:8002/&scope=userinfo
+ http://sa-oauth-server.com:8000/oauth2/authorize?response_type=token&client_id=1001&redirect_uri=http://sa-oauth-client.com:8002/&scope=userinfo
http://sa-oauth-server.com:8001/oauth2/token?grant_type=password&client_id={value}&client_secret={value}&username={value}&password={value}
+ http://sa-oauth-server.com:8000/oauth2/token?grant_type=password&client_id={value}&client_secret={value}&username={value}&password={value}
以上三种模式获取的都是用户的 Access-Token,代表用户对第三方应用的授权,在OAuth2.0中还有一种针对 Client级别的授权, 即:Client-Token,代表应用自身的资源授权
-Client-Token具有延迟作废特性,即:在每次获取最新Client-Token的时候,旧Client-Token不会立即过期,而是作为Past-Token再次 +
Client-Token具有延迟作废特性,即:在每次获取最新Client-Token的时候,旧Client-Token不会立即过期,而是作为Lower-Client-Token再次 储存起来,资源请求方只要携带其中之一便可通过Token校验,这种特性保证了在大量并发请求时不会出现“新旧Token交替造成的授权失效”, 保证了服务的高可用
-http://sa-oauth-server.com:8001/oauth2/client_token?grant_type=client_credentials&client_id={value}&client_secret={value}
+ http://sa-oauth-server.com:8000/oauth2/client_token?grant_type=client_credentials&client_id={value}&client_secret={value}