Issue with collecting AspectJ pointcut context and avoiding mentioning all arguments of the advised method

StackOverflow https://stackoverflow.com/questions/18858447

Question

I use AspectJ in order to check whether an object does belong to the current user. The advised method is actually a Spring MVC controller method. I use an annotation placed on that controller method in order to apply the crosscutting security advice.

The issue I have is that the controller method has quite a few arguments. I would like to avoid mentioning all arguments in the aspectJ source because those can change (argument name, type, etc.) but I still have to collect the pointcut context.

To sum up of the N arguments present in the method, I only need to use two (member and advertisementId). How can I avoid mentioning the N arguments?

My pointcut:

public pointcut advertisementBelongsToMemberControllerCheck(FamilyAdvertisementInfo familyAdvertisementInfo, long advertisementId, Model model, Member member) 
        : execution(@AdvertisementExistsAndBelongsToMemberCheck * * (..)) 
        && args(familyAdvertisementInfo,advertisementId, model,  member);

My advice:

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!");
        }
    }

The annotation:

@Retention(RetentionPolicy.RUNTIME)
public @interface AdvertisementExistsAndBelongsToMemberCheck {

}

And finally, the advised controller method:

@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";
    }
Was it helpful?

Solution

Just in case someone is interested, I was given an answer to my question. Here it is:

My pointcut:

public pointcut advertisementBelongsToMemberControllerCheck(long advertisementId, Member member) 

: execution(@AdvertisementExistsAndBelongsToMemberCheck * * (..)) 
        && args(*, advertisementId, *, member, ..);

My advice:

before(long advertisementId, Member member) : advertisementBelongsToMemberControllerCheck(advertisementId, member) {

        if (!advertisementService.advertisementExistsAndBelongsToMember(advertisementId, member)) {
            throw new AccessDeniedException("Advertisement does not belong to member!");
        }
    }

This works and it is much cleaner.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top