Spring 使用方面的引导角色验证控制器

Spring Boot role validation controller using aspect

我有几个按角色分隔的控制器函数,我发现它似乎可以通过使用 Aspect 来完成,而不是在每个控制器方法中进行角色验证,但是我的实现中有些地方不对Aspect 中的代码永远不会运行

注解:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ForMerchantOnly {}

看点:

@Aspect
@Configuration
public class ForMerchantOnlyAspect {
    private static final Logger logger = LogManager.getLogger(ForMerchantOnlyAspect.class);

    @Before("@annotation(com.example.api.annotation.ForMerchantOnly) && args(request)")
    public void before(HttpServletRequest request) throws ServiceException {
        if (!(request instanceof HttpServletRequest)) {
            throw new RuntimeException("request should be HttpServletRequesttype");
        }

        String domain = request.getServerName();
        System.out.println("Aspect showing domain " + domain);
        // -- other code
    }
}

控制器

@ForMerchantOnly
@GetMapping("/list")
public ResponseEntity<ApiResp> list() {
    System.out.println("Show something");
    return ResponseEntity.ok().body();
}

我假设当我通过 chrome 浏览器调用控制器 /list 方法时,它会命中 ForMerchantOnlyAspect 中的代码,但它只是直接进入控制器方法。我错过了什么吗?

方面没有工作,因为它找不到匹配的连接点。没有具有注解 @ForMerchantOnly 且参数类型为 HttpServletRequest

的控制器方法

来自 documentation :

args: Limits matching to join points (the execution of methods when using Spring AOP) where the arguments are instances of the given types.

以下方面可用于需求。范围指示符 within 将范围设置为建议。

@Before("@annotation(com.example.api.annotation.ForMerchantOnly) && within(com.example.api..*)")
  public void before() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
                .getRequest();

        System.out.println("Aspect showing domain " + request.getServerName());
    }

另请注意,使用 @Component@Configuration 注释更好地用于配置。

您还可以查看 Spring 安全框架的 Method Security,它可以使用注释保护方法。

来自文档

From version 2.0 onwards Spring Security has improved support substantially for adding security to your service layer methods. It provides support for JSR-250 annotation security as well as the framework’s original @Secured annotation. From 3.0 you can also make use of new expression-based annotations. You can apply security to a single bean, using the intercept-methods element to decorate the bean declaration, or you can secure multiple beans across the entire service layer using the AspectJ style pointcuts.