Почему @PreAuthorize не будет проверяться, если вызывается в хранилище? - PullRequest
1 голос
/ 14 апреля 2020

Я искал способы обойти @PreAuthorize, если сам вызываю код, и, к удивлению, работает следующее:

@RepositoryRestResource(excerptProjection = UserSummaryProjection.class)
public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {

    /**
     * Saves entity without security checks.
     */
    @RestResource(exported = false)
    default User saveInternal(User entity) {
        return save(entity);
    }

    @PreAuthorize("@userValidator.hasWritePermission(#user)")
    @Override
    User save(User user);
}

А потом где-нибудь в коде моего контроллера ..

public @ResponseBody
    ResponseEntity<?> controllerMethod(@RequestBody param) {
    userRepository.saveInternal(user);   //does not PreAuthorize check
    userRepository.save(user);   //does DO PreAuthorize check
}

Это работает так, как я хочу, но почему это работает? Потому что saveInternal в конечном итоге просто не вызовет save () и поэтому требует проверки?

1 Ответ

1 голос
/ 14 апреля 2020

Spring security создает прокси для проверки безопасности.

В вашем случае при запуске генерируется прокси, который реализует интерфейс UserRepository. Компонент B, реализующий интерфейс, теоретически вводится через компонент @Resource в компоненте A. Но на самом деле это ссылка на прокси, который вводится. Поэтому, когда Bean A вызывает метод Bean B, он вызывает прокси.

A --> proxy --> B

Но если метод B (saveInternal) вызывает другой метод B (save), он не получить снова через прокси, он напрямую вызывает метод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...