iank
iank

Reputation: 113

Reference this in Spring's @PreAuthorize

I have an abstract controller ApiRestController where I declared a common endpoint which delegates the service call to the child class APICustomRestController.

public abstract class ApiRestController extends BaseRestController {
public static final String TEAMS_ENDPOINT = "/teams";

protected abstract Page<? extends ResponseDto> getTeamsData(int page);
public abstract int getApiCode();

@GetMapping(TEAMS_ENDPOINT)
@PreAuthorize("@aclService.checkAcl(#authentication, #this.getApiCode())")
public Page<? extends ResponseDto> getTeams(Authentication authentication, @RequestParam Optional<Integer> p) {
    return getTeamsData(p.orElse(0));
}
}


@RestController("apiCustomController")
@RequestMapping( API)
public class APICustomRestController extends ApiRestController {
public static final String API = "/custom";
private final TeamDataDtoService teamDataDtoService;

@Autowired
public APICustomRestController(TeamDataDtoService teamDataDtoService) {
    this.teamDataDtoService = teamDataDtoService;
}

@Override
protected Page<? extends ResponseDto> getTeamsData(int page) {
    return teamDataDtoService.getDtoPage(page, 10, "name");
}

@Override
public int getApiCode() {
    return 0; // some key to check authorization
}
}

Before the call reaches the service layer, I need to check if the caller does have required authorities to access the endpoint. I have tried @PreAuthorize("@aclService.checkAcl(#authentication, #this.getApiCode())"), but IDE gives warning about #this as it cannot be resolved. @aclService is an actual bean, which checks the authorization and returns a boolean (if I try to put static value e.g. @PreAuthorize("@aclService.checkAcl(#authentication, 0)") - that works). With dynamic call to #this.getApiCode() in runtime, I get the exception with message:

Failed to evaluate expression '@aclService.checkAcl(#authentication, #this.getApiCode())'

I have checked the docs, where it says that you can access #that or #root:

The variable #this is always defined and refers to the current evaluation object (against which unqualified references are resolved). The variable #root is always defined and refers to the root context object. Although #this may vary as components of an expression are evaluated, #root always refers to the root.

What am I missing here?

Upvotes: 0

Views: 50

Answers (0)

Related Questions