在Spring Boot中,可以使用切面编程来实现不同角色账号看到的数据不同的功能。下面是一个示例:
首先,定义一个自定义的注解 @RoleAccess
,用于标注在需要进行角色访问控制的方法上:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RoleAccess {
String[] roles();
}
接着,创建一个切面类 RoleAccessAspect
,用于拦截带有 @RoleAccess
注解的方法,并根据当前用户的角色进行访问控制:
@Aspect
@Component
public class RoleAccessAspect {
@Before("@annotation(roleAccess)")
public void before(JoinPoint joinPoint, RoleAccess roleAccess) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
String currentRole = authentication.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.joining(","));
if (!Arrays.asList(roleAccess.roles()).contains(currentRole)) {
throw new AccessDeniedException("Access Denied");
}
}
}
}
在上面的切面类中,通过 @Before
注解和 @annotation(roleAccess)
使用了切点表达式,表示拦截带有 @RoleAccess
注解的方法,并在方法执行前进行访问控制。
然后,在需要进行访问控制的方法上添加 @RoleAccess
注解,指定不同角色具有访问权限的配置,例如:
@RestController
public class DataController {
@RoleAccess(roles = {"admin"})
@GetMapping("/data")
public String getDataForAdmin() {
return "This data is only accessible to admins";
}
@RoleAccess(roles = {"user"})
@GetMapping("/data")
public String getDataForUser() {
return "This data is only accessible to users";
}
}
在上面的示例中,同一个接口路径 /data
根据不同角色的配置,返回不同的数据。
最后,需要在启动类上添加 @EnableAspectJAutoProxy
注解启用切面:
@SpringBootApplication
@EnableAspectJAutoProxy
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
这样,当不同角色的账号访问相应的接口时,切面会根据当前用户的角色进行访问控制,确保只有具有访问权限的角色可以看到相应的数据。