From 459739b212afc482fd1b8332c9d424fbcf4d5c01 Mon Sep 17 00:00:00 2001 From: Bunny <1319900154@qq.com> Date: Tue, 15 Jul 2025 09:19:43 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E6=A8=A1=E6=9D=BF=E5=85=83?= =?UTF-8?q?=E6=B3=A8=E8=A7=A3=E7=9A=84=E6=B7=B1=E5=85=A5=E4=BD=BF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spring-security/ReadMe.md | 29 +++++++++++++ .../spring/step2/config/Knife4jConfig.java | 9 ---- .../{ => test}/CheckController.java | 2 +- .../test/SecurityAdminController.java | 41 +++++++++++++++++++ ...ontroller.java => SecurityController.java} | 6 +-- .../SecurityHasAnyAuthorityController.java | 40 ++++++++++++++++++ ...oller.java => SecurityUserController.java} | 6 +-- .../security/annotation/HasAnyAuthority.java | 15 +++++++ .../step2/security/annotation/IsAdmin.java | 17 ++++++++ .../config/SecurityConfiguration.java | 6 +++ .../src/main/resources/templates/index.html | 2 +- 11 files changed, 156 insertions(+), 17 deletions(-) rename spring-security/step-2/src/main/java/com/spring/step2/controller/{ => test}/CheckController.java (97%) create mode 100644 spring-security/step-2/src/main/java/com/spring/step2/controller/test/SecurityAdminController.java rename spring-security/step-2/src/main/java/com/spring/step2/controller/test/{TestController.java => SecurityController.java} (93%) create mode 100644 spring-security/step-2/src/main/java/com/spring/step2/controller/test/SecurityHasAnyAuthorityController.java rename spring-security/step-2/src/main/java/com/spring/step2/controller/test/{TestAdminController.java => SecurityUserController.java} (89%) create mode 100644 spring-security/step-2/src/main/java/com/spring/step2/security/annotation/HasAnyAuthority.java create mode 100644 spring-security/step-2/src/main/java/com/spring/step2/security/annotation/IsAdmin.java diff --git a/spring-security/ReadMe.md b/spring-security/ReadMe.md index aab1bc5..6084dcd 100644 --- a/spring-security/ReadMe.md +++ b/spring-security/ReadMe.md @@ -1078,6 +1078,35 @@ public @interface UserOrPermission { public Report getReport(Long id) { ... } ``` +**自定义Any模板元注解** + +如果需要自定义任意权限都可通过需要引入下面的内容。 + +```java +@Bean +static PrePostTemplateDefaults prePostTemplateDefaults() { + return new PrePostTemplateDefaults(); +} +``` + +**示例** + +```java +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@PreAuthorize("hasAnyAuthority({auth})") +public @interface HasAnyAuthority { + String[] auth(); +} + +@HasAnyAuthority(auth = {"'USER'", "'ADMIN'"}) +@Operation(summary = "拥有 HasAnyXXX 的角色可以访问", description = "当前用户拥有 HasAnyXXX 角色可以访问这个接口") +@GetMapping("role-user") +public Result roleUser() { + return Result.success(); +} +``` + ### 4. 其他注解支持 #### JSR-250注解 diff --git a/spring-security/step-2/src/main/java/com/spring/step2/config/Knife4jConfig.java b/spring-security/step-2/src/main/java/com/spring/step2/config/Knife4jConfig.java index ce43a1f..a736c91 100644 --- a/spring-security/step-2/src/main/java/com/spring/step2/config/Knife4jConfig.java +++ b/spring-security/step-2/src/main/java/com/spring/step2/config/Knife4jConfig.java @@ -47,13 +47,4 @@ public class Knife4jConfig { return GroupedOpenApi.builder().group("security接口").pathsToMatch("/api/security/**").build(); } - @Bean - public GroupedOpenApi test() { - return GroupedOpenApi.builder().group("测试接口").pathsToMatch("/api/test/**").build(); - } - - @Bean - public GroupedOpenApi testAdmin() { - return GroupedOpenApi.builder().group("测试包含管理员接口").pathsToMatch("/api/test-admin/**").build(); - } } diff --git a/spring-security/step-2/src/main/java/com/spring/step2/controller/CheckController.java b/spring-security/step-2/src/main/java/com/spring/step2/controller/test/CheckController.java similarity index 97% rename from spring-security/step-2/src/main/java/com/spring/step2/controller/CheckController.java rename to spring-security/step-2/src/main/java/com/spring/step2/controller/test/CheckController.java index ea7dae0..0f39eba 100644 --- a/spring-security/step-2/src/main/java/com/spring/step2/controller/CheckController.java +++ b/spring-security/step-2/src/main/java/com/spring/step2/controller/test/CheckController.java @@ -1,4 +1,4 @@ -package com.spring.step2.controller; +package com.spring.step2.controller.test; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; diff --git a/spring-security/step-2/src/main/java/com/spring/step2/controller/test/SecurityAdminController.java b/spring-security/step-2/src/main/java/com/spring/step2/controller/test/SecurityAdminController.java new file mode 100644 index 0000000..b4e108b --- /dev/null +++ b/spring-security/step-2/src/main/java/com/spring/step2/controller/test/SecurityAdminController.java @@ -0,0 +1,41 @@ +package com.spring.step2.controller.test; + +import com.spring.step2.domain.vo.result.Result; +import com.spring.step2.security.annotation.IsAdmin; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "ADMIN接口", description = "只要包含 Admin 角色都可以访问") +@Slf4j +@RestController +@RequestMapping("/api/security/admin") +public class SecurityAdminController { + + @IsAdmin + @Operation(summary = "拥有 IsAdmin 的角色可以访问", description = "当前用户拥有 IsAdmin 角色可以访问这个接口") + @GetMapping("role-user") + public Result roleUser() { + return Result.success(); + } + + @IsAdmin + @Operation(summary = "拥有 IsAdmin 的角色可以访问", description = "当前用户拥有 IsAdmin 角色可以访问这个接口") + @GetMapping("upper-user") + public Result upperUser() { + String data = "是区分大小写的"; + return Result.success(data); + } + + @IsAdmin + @Operation(summary = "拥有 IsAdmin 的角色可以访问", description = "当前用户拥有 IsAdmin 角色可以访问这个接口") + @GetMapping("lower-user") + public Result lowerUser() { + String data = "如果是大写,但是在这里是小写无法访问"; + return Result.success(data); + } + +} diff --git a/spring-security/step-2/src/main/java/com/spring/step2/controller/test/TestController.java b/spring-security/step-2/src/main/java/com/spring/step2/controller/test/SecurityController.java similarity index 93% rename from spring-security/step-2/src/main/java/com/spring/step2/controller/test/TestController.java rename to spring-security/step-2/src/main/java/com/spring/step2/controller/test/SecurityController.java index 0b89f0e..8b0a4bb 100644 --- a/spring-security/step-2/src/main/java/com/spring/step2/controller/test/TestController.java +++ b/spring-security/step-2/src/main/java/com/spring/step2/controller/test/SecurityController.java @@ -10,11 +10,11 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -@Tag(name = "测试接口", description = "测试用的接口") +@Tag(name = "NORMAl接口", description = "测试用的NORMAl接口") @Slf4j @RestController -@RequestMapping("/api/test") -public class TestController { +@RequestMapping("/api/security/normal") +public class SecurityController { @PreAuthorize("hasAuthority('role::read')") @Operation(summary = "拥有 role:read 的角色可以访问", description = "当前用户拥有 role:read 角色可以访问这个接口") diff --git a/spring-security/step-2/src/main/java/com/spring/step2/controller/test/SecurityHasAnyAuthorityController.java b/spring-security/step-2/src/main/java/com/spring/step2/controller/test/SecurityHasAnyAuthorityController.java new file mode 100644 index 0000000..d1ef070 --- /dev/null +++ b/spring-security/step-2/src/main/java/com/spring/step2/controller/test/SecurityHasAnyAuthorityController.java @@ -0,0 +1,40 @@ +package com.spring.step2.controller.test; + +import com.spring.step2.domain.vo.result.Result; +import com.spring.step2.security.annotation.HasAnyAuthority; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "ANY ROLES", description = "只要包含 ANY 角色都可以访问") +@Slf4j +@RestController +@RequestMapping("/api/security/any") +public class SecurityHasAnyAuthorityController { + + @HasAnyAuthority(auth = {"'USER'", "'ADMIN'"}) + @Operation(summary = "拥有 HasAnyXXX 的角色可以访问", description = "当前用户拥有 HasAnyXXX 角色可以访问这个接口") + @GetMapping("role-user") + public Result roleUser() { + return Result.success(); + } + + @HasAnyAuthority(auth = {"'USER'", "'ADMIN'"}) + @Operation(summary = "拥有 HasAnyXXX 的角色可以访问", description = "当前用户拥有 HasAnyXXX 角色可以访问这个接口") + @GetMapping("upper-user") + public Result upperUser() { + String data = "是区分大小写的"; + return Result.success(data); + } + + @HasAnyAuthority(auth = {"'USER'", "'ADMIN'"}) + @Operation(summary = "拥有 HasAnyXXX 的角色可以访问", description = "当前用户拥有 HasAnyXXX 角色可以访问这个接口") + @GetMapping("lower-user") + public Result lowerUser() { + String data = "如果是大写,但是在这里是小写无法访问"; + return Result.success(data); + } +} diff --git a/spring-security/step-2/src/main/java/com/spring/step2/controller/test/TestAdminController.java b/spring-security/step-2/src/main/java/com/spring/step2/controller/test/SecurityUserController.java similarity index 89% rename from spring-security/step-2/src/main/java/com/spring/step2/controller/test/TestAdminController.java rename to spring-security/step-2/src/main/java/com/spring/step2/controller/test/SecurityUserController.java index 27763b3..e5933b7 100644 --- a/spring-security/step-2/src/main/java/com/spring/step2/controller/test/TestAdminController.java +++ b/spring-security/step-2/src/main/java/com/spring/step2/controller/test/SecurityUserController.java @@ -9,11 +9,11 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -@Tag(name = "测试包含 USER 接口", description = "只要包含 USER 角色都可以访问") +@Tag(name = "USER测试", description = "只要包含 USER 角色都可以访问") @Slf4j @RestController -@RequestMapping("/api/test-admin") -public class TestAdminController { +@RequestMapping("/api/security/user") +public class SecurityUserController { @HasUSERAuthorize("role:read") @Operation(summary = "拥有 role:read 的角色可以访问", description = "当前用户拥有 role:read 角色可以访问这个接口") diff --git a/spring-security/step-2/src/main/java/com/spring/step2/security/annotation/HasAnyAuthority.java b/spring-security/step-2/src/main/java/com/spring/step2/security/annotation/HasAnyAuthority.java new file mode 100644 index 0000000..be95c50 --- /dev/null +++ b/spring-security/step-2/src/main/java/com/spring/step2/security/annotation/HasAnyAuthority.java @@ -0,0 +1,15 @@ +package com.spring.step2.security.annotation; + +import org.springframework.security.access.prepost.PreAuthorize; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@PreAuthorize("hasAnyAuthority({auth})") +public @interface HasAnyAuthority { + String[] auth(); +} \ No newline at end of file diff --git a/spring-security/step-2/src/main/java/com/spring/step2/security/annotation/IsAdmin.java b/spring-security/step-2/src/main/java/com/spring/step2/security/annotation/IsAdmin.java new file mode 100644 index 0000000..35fbb8e --- /dev/null +++ b/spring-security/step-2/src/main/java/com/spring/step2/security/annotation/IsAdmin.java @@ -0,0 +1,17 @@ +package com.spring.step2.security.annotation; + +import org.springframework.security.access.prepost.PreAuthorize; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 判断当前是否是Admin用户 + */ +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@PreAuthorize("hasAuthority('ADMIN')") +public @interface IsAdmin { +} \ No newline at end of file diff --git a/spring-security/step-2/src/main/java/com/spring/step2/security/config/SecurityConfiguration.java b/spring-security/step-2/src/main/java/com/spring/step2/security/config/SecurityConfiguration.java index 0ce879e..fa84a07 100644 --- a/spring-security/step-2/src/main/java/com/spring/step2/security/config/SecurityConfiguration.java +++ b/spring-security/step-2/src/main/java/com/spring/step2/security/config/SecurityConfiguration.java @@ -3,6 +3,7 @@ package com.spring.step2.security.config; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.authorization.method.PrePostTemplateDefaults; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; @@ -13,6 +14,11 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager; @Configuration public class SecurityConfiguration { + @Bean + PrePostTemplateDefaults prePostTemplateDefaults() { + return new PrePostTemplateDefaults(); + } + /** * 添加内存用户 * diff --git a/spring-security/step-2/src/main/resources/templates/index.html b/spring-security/step-2/src/main/resources/templates/index.html index 5aed25b..f302ee4 100644 --- a/spring-security/step-2/src/main/resources/templates/index.html +++ b/spring-security/step-2/src/main/resources/templates/index.html @@ -379,7 +379,7 @@