模板元注解的深入使用

This commit is contained in:
Bunny 2025-07-15 09:19:43 +08:00
parent fae4d505de
commit 459739b212
11 changed files with 156 additions and 17 deletions

View File

@ -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<String> roleUser() {
return Result.success();
}
```
### 4. 其他注解支持
#### JSR-250注解

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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<String> roleUser() {
return Result.success();
}
@IsAdmin
@Operation(summary = "拥有 IsAdmin 的角色可以访问", description = "当前用户拥有 IsAdmin 角色可以访问这个接口")
@GetMapping("upper-user")
public Result<String> upperUser() {
String data = "是区分大小写的";
return Result.success(data);
}
@IsAdmin
@Operation(summary = "拥有 IsAdmin 的角色可以访问", description = "当前用户拥有 IsAdmin 角色可以访问这个接口")
@GetMapping("lower-user")
public Result<String> lowerUser() {
String data = "如果是大写,但是在这里是小写无法访问";
return Result.success(data);
}
}

View File

@ -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 角色可以访问这个接口")

View File

@ -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<String> roleUser() {
return Result.success();
}
@HasAnyAuthority(auth = {"'USER'", "'ADMIN'"})
@Operation(summary = "拥有 HasAnyXXX 的角色可以访问", description = "当前用户拥有 HasAnyXXX 角色可以访问这个接口")
@GetMapping("upper-user")
public Result<String> upperUser() {
String data = "是区分大小写的";
return Result.success(data);
}
@HasAnyAuthority(auth = {"'USER'", "'ADMIN'"})
@Operation(summary = "拥有 HasAnyXXX 的角色可以访问", description = "当前用户拥有 HasAnyXXX 角色可以访问这个接口")
@GetMapping("lower-user")
public Result<String> lowerUser() {
String data = "如果是大写,但是在这里是小写无法访问";
return Result.success(data);
}
}

View File

@ -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 角色可以访问这个接口")

View File

@ -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();
}

View File

@ -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 {
}

View File

@ -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();
}
/**
* 添加内存用户
*

View File

@ -379,7 +379,7 @@
</div>
<ul class="nav-links">
<li><a href="#features">特性</a></li>
<li><a href="#docs" target="_blank">文档</a></li>
<li><a href="#docs">文档</a></li>
<li><a href="/user" target="_blank">用户管理</a></li>
<li><a href="/login" target="_blank">登录</a></li>
</ul>