1

In my Backend, I have added @PreAuthorize("hasRole('ROLE_ADMIN') to allow user to access the functions in service layer. And now I would like to use my schedule job (springframework scheduling) to access these service but obviously it can not. My question is how can I add ROLE_ADMIN role or generate a user principal for the schedule job?

@PreAuthorize("hasRole('ROLE_ADMIN')")
JsonNode loadSMS(String additionalPath) {
    .....
}
anguspcw
  • 306
  • 2
  • 18
  • Possible duplicate of https://stackoverflow.com/questions/29684505/how-can-i-authenticate-a-system-user-for-scheduled-processes-in-spring – dur Mar 01 '19 at 10:29
  • Possible duplicate of https://stackoverflow.com/questions/47078381/securitycontext-with-default-system-authentication-user – dur Mar 01 '19 at 10:38

2 Answers2

1

Either have another method not annotated with the @PreAuthorize which your scheduler calls. Move the implementation into this new method, and change the existing loadSMS to use this new method to reduce code duplication. Otherwise you could add a role at runtime, but I don't think that is such a great idea.

Derrops
  • 7,651
  • 5
  • 30
  • 60
1

You can try below code

@Service
class SchedulerService {
    @Autowired
    private YourService service;

    @Scheduled(fixedRate = 600000L, initialDelay = 60000L)
    public void executeTask() throws IOException {
        RunAs.runAsAdmin(() -> {
          service.loadSMS(String additionalPath) {
        });
    }
}

public class RunAs {

    @FunctionalInterface
    public interface RunAsMethod {
        default void run() {
            try {
                runWithException();
            } catch (Exception e) {

            }
        }
        void runWithException() throws Exception;
    }

    public static void runAsAdmin(final RunAsMethod func) {
        final AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("adminUser", "adminPassword",
                ImmutableList.of(new SimpleGrantedAuthority("ROLE_ADMIN")));
        final Authentication originalAuthentication = SecurityContextHolder.getContext().getAuthentication();
        SecurityContextHolder.getContext().setAuthentication(token);
        func.run();
        SecurityContextHolder.getContext().setAuthentication(originalAuthentication);
    }
}
ManojP
  • 6,113
  • 2
  • 37
  • 49