diff --git a/spring-security/ReadMe.md b/spring-security/ReadMe.md index 6084dcd..9fd503b 100644 --- a/spring-security/ReadMe.md +++ b/spring-security/ReadMe.md @@ -1080,6 +1080,10 @@ public Report getReport(Long id) { ... } **自定义Any模板元注解** +> [!WARNING] +> +> SpringSecurity6.3.10版本与最新版的6.5.1写法不一样。 + 如果需要自定义任意权限都可通过需要引入下面的内容。 ```java @@ -1206,4 +1210,31 @@ public class AuthTestController { public Content getContent(Long id) { // 需要管理员权限且只允许返回公开内容 } - ``` \ No newline at end of file + ``` + +## 通过编程方式授权方法 + +```java +@Component("auth") +public class AuthorizationLogic { + + public boolean decide(String name) { + System.out.println(name); + // 直接使用name的实现 + return name.equalsIgnoreCase("user"); + } + +} +``` + +在控制器中使用 + +```java +@PreAuthorize("@auth.decide(#name)") +@Operation(summary = "拥有 USER 的角色可以访问", description = "当前用户拥有 USER 角色可以访问这个接口") +@GetMapping("lower-user") +public Result lowerUser(String name) { + return Result.success(name); +} +``` + diff --git a/spring-security/step-2/src/main/java/com/spring/step2/controller/test/SecurityProgrammaticallyController.java b/spring-security/step-2/src/main/java/com/spring/step2/controller/test/SecurityProgrammaticallyController.java new file mode 100644 index 0000000..a069252 --- /dev/null +++ b/spring-security/step-2/src/main/java/com/spring/step2/controller/test/SecurityProgrammaticallyController.java @@ -0,0 +1,32 @@ +package com.spring.step2.controller.test; + +import com.spring.step2.domain.vo.result.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "Programmatically", description = "只要包含 Programmatically 角色都可以访问") +@Slf4j +@RestController +@RequestMapping("/api/security/programmatically") +public class SecurityProgrammaticallyController { + + @Operation(summary = "拥有 USER 的角色可以访问", description = "当前用户拥有 USER 角色可以访问这个接口") + @GetMapping("upper-user") + public Result upperUser() { + String data = "是区分大小写的"; + return Result.success(data); + } + + @PreAuthorize("@auth.decide(#name)") + @Operation(summary = "拥有 USER 的角色可以访问", description = "当前用户拥有 USER 角色可以访问这个接口") + @GetMapping("lower-user") + public Result lowerUser(String name) { + return Result.success(name); + } + +} diff --git a/spring-security/step-2/src/main/java/com/spring/step2/security/annotation/programmatically/AuthorizationLogic.java b/spring-security/step-2/src/main/java/com/spring/step2/security/annotation/programmatically/AuthorizationLogic.java new file mode 100644 index 0000000..e9cad33 --- /dev/null +++ b/spring-security/step-2/src/main/java/com/spring/step2/security/annotation/programmatically/AuthorizationLogic.java @@ -0,0 +1,14 @@ +package com.spring.step2.security.annotation.programmatically; + +import org.springframework.stereotype.Component; + +@Component("auth") +public class AuthorizationLogic { + + public boolean decide(String name) { + System.out.println(name); + // 直接使用name的实现 + return name.equalsIgnoreCase("user"); + } + +} \ 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 fa84a07..976892f 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 @@ -14,6 +14,32 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager; @Configuration public class SecurityConfiguration { + /** + * 注册一个用于Spring Security预授权/后授权的模板元注解默认配置Bean。 + * + *

该Bean提供了基于SpEL表达式的权限校验模板,可用于自定义组合注解。

+ * + *

典型用法

+ *

通过此配置可以简化自定义权限注解的定义,例如:

+ *
{@code
+     * @Target({ElementType.METHOD, ElementType.TYPE})
+     * @Retention(RetentionPolicy.RUNTIME)
+     * @PreAuthorize("hasAnyAuthority(  // 使用模板提供的表达式语法
+     * public @interface HasAnyAuthority {
+     *     String[] auth();  // 接收权限列表参数
+     * }
+     * }
+ * + *

注意事项

+ *
    + *
  • 需要确保Spring Security的预授权功能已启用
  • + *
  • 模板表达式应符合SpEL语法规范
  • + *
+ * + * @return PrePostTemplateDefaults 实例,用于预/后授权注解的默认配置 + * @see org.springframework.security.access.prepost.PreAuthorize + * @see org.springframework.security.access.prepost.PostAuthorize + */ @Bean PrePostTemplateDefaults prePostTemplateDefaults() { return new PrePostTemplateDefaults();