我有几个按角色分隔的控制器函数,而不是在每个控制器方法中进行角色验证,我发现它似乎可以通过使用 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
但它只是直接进入控制器方法。我错过了什么吗?
Aspect 无法工作,因为它找不到匹配的 joinpoint 。没有具有注释@ForMerchantOnly
和类型参数的控制器方法HttpServletRequest
从文档:
args:限制匹配连接点(使用 Spring AOP 时的方法执行),其中参数是给定类型的实例。
以下方面可用于要求。范围指示符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());
}
另请注意,Aspect 最好使用注释@Component
并@Configuration
用于配置。
您还可以查看Spring 安全框架的方法安全性,它可以使用注释来保护方法。
从文档
从 version 2.0 开始,Spring Security 大大改进了对为您的服务层方法添加安全性的支持。它提供对 JSR-250 注释安全性以及框架原始 @Secured 注释的支持。从 3.0 开始,您还可以使用新的基于表达式的注释。您可以将安全性应用于单个 bean,使用intercept-methods 元素来装饰bean 声明,或者您可以使用AspectJ 样式切入点保护整个服务层中的多个bean。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句