我使用AspectJ来检查对象是否属于当前用户。建议的方法实际上是Spring MVC控制器方法。我使用放置在该控制器方法上的注释来应用横切安全建议。
我遇到的问题是控制器方法有很多参数。我想避免提及 aspectJ 源中的所有参数,因为这些参数可以更改(参数名称、类型等),但我仍然必须收集切入点上下文。
为了总结方法中存在的 N 个参数,我只需要使用两个(成员和广告 ID)。如何避免提及 N 参数?
我的切入点:
public pointcut advertisementBelongsToMemberControllerCheck(FamilyAdvertisementInfo familyAdvertisementInfo, long advertisementId, Model model, Member member)
: execution(@AdvertisementExistsAndBelongsToMemberCheck * * (..))
&& args(familyAdvertisementInfo,advertisementId, model, member);
我的建议:
before(FamilyAdvertisementInfo familyAdvertisementInfo, long advertisementId, Model model, Member member) : advertisementBelongsToMemberControllerCheck(familyAdvertisementInfo,advertisementId, model, member) {
if (!advertisementService.advertisementExistsAndBelongsToMember(advertisementId, member)) {
throw new AccessDeniedException("Advertisement does not belong to member!");
}
}
注释:
@Retention(RetentionPolicy.RUNTIME)
public @interface AdvertisementExistsAndBelongsToMemberCheck {
}
最后,建议的控制器方法:
@RequestMapping(value = "/family/edit/{advertisementId}", method = RequestMethod.GET, produces = "text/html")
@AdvertisementExistsAndBelongsToMemberCheck
public String editFamilyAdvertisementForm(@ModelAttribute FamilyAdvertisementInfo familyAdvertisementInfo, @PathVariable long advertisementId, Model model, @CurrentMember Member member/* the currently logged in user */) {
FamilyAdvertisement advertisement = advertisementService.findFamilyAdvertisement(advertisementId);
familyAdvertisementInfo.setFamilyAdvertisement(advertisement);
populateFamilyAdvertisementModel(model, familyAdvertisementInfo, member);
return "advertisement/family/edit";
}
以防万一有人感兴趣,我的问题得到了答案。在这里:
我的切入点:
public pointcut advertisementBelongsToMemberControllerCheck(long advertisementId, Member member)
: execution(@AdvertisementExistsAndBelongsToMemberCheck * * (..))
&& args(*, advertisementId, *, member, ..);
我的建议:
before(long advertisementId, Member member) : advertisementBelongsToMemberControllerCheck(advertisementId, member) {
if (!advertisementService.advertisementExistsAndBelongsToMember(advertisementId, member)) {
throw new AccessDeniedException("Advertisement does not belong to member!");
}
}
这有效,而且更干净。