I'm using Spring Boot 1.5.3, Spring Security, Sping JPA, Hibernate. I've several repositories where I'm using security annotations:
@Transactional
@PreAuthorize("isAuthenticated()")
public interface DailyCodeRepository extends PagingAndSortingRepository<DailyCode, Long> {
@Query("SELECT MAX(date) FROM DailyCode d ")
public LocalDate findLastCodeDate();
@Query("SELECT COUNT(d) FROM DailyCode d WHERE code=:code AND date>=DATE(:date)")
public long countDailyCodesByCodeGreaterThanDate(@Param("code") @RequestParam(value = "code", required = true) String code,
@Param("date") @RequestParam(value = "untdateil", required = true) Instant date);
}
I've a task class like this that calls a secured method:
@Component
@Transactional
public class DailyCodeTask {
@Value("${dailyCodes.generator.number}")
private int codesToGenerate;
@Scheduled(cron = "${task.dailyCodes}")
public void run() {
//secured method!!
LocalDate startDate = dailyCodeRepository.findLastCodeDate();
}
}
Right now I've an exception when the task starts because Spring doesn't find the Authentication in the SecurityContext.
8/07/2017 14:39:00,007 ERROR pool-3-thread-1 TaskUtils$LoggingErrorHandler:95 - Unexpected error occurred in scheduled task.
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
This is not a surprise of course. I was wondering what is the best practice to solve this problem.
- create a service that doesn't require for authentication seems overkilled. I've to create a lot of code when I've already a method ready in the repository
- Set a Security auth programatically: seems good, but is it safe? I found an old article here.
If the option 2 is the best, I would like to know the best practice to use with Spring 4.3.x.