Доступ к защищенному репозиторию при аутентификации с пружиной - PullRequest
0 голосов
/ 23 октября 2018

Я работаю над базовым приложением, которое должно генерировать - с помощью упругости данных пружины - некоторые стандартные конечные точки отдыха для разных объектов.Конечные точки должны быть доступны только для пользователей с определенной ролью (с помощью весенней защиты).

В данный момент моя служба пользовательских данных загружает информацию из базы данных для создания UserDetails объектов во время аутентификации.

@Service
public class MyUserDetailsService implements UserDetailsService {
    @Setter(onMethod=@__({@Autowired}))
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException(username));

        return org.springframework.security.core.userdetails.User.builder()
                .username(user.getUsername())
                .password(user.getPassword())
                .roles(user.getRoles())
                .build();
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

Теперь я пытаюсь обеспечить безопасность на уровне метода для моих конечных точек.

@PreAuthorize("hasRole('USER')")
public interface UserRepository extends JpaRepository<User, Long> {
    @PreAuthorize("permitAll()")
    Optional<User> findByUsername(String username);
}

Проблема в том, что loadUserByUsername явно используется во время аутентификации.В методе я использую метод findByUsername, описанный выше.Даже если он настроен на permitAll(), он все равно пытается что-то сделать с SecurityContext.По крайней мере, я получаю следующую ошибку при попытке доступа к конечной точке:

org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext

Я думаю, что в настоящее время я нахожусь в процессе создания SecurityContext, и поэтому он все еще пуст.

Если я изменю свой репозиторий на

public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByUsername(String username);
}

, он будет работать, но тогда мои конечные точки будут открыты для всех.


Вопросы

  • Есть ли что-то принципиально неправильное в том, что я делаю?
  • Если нет, как я могу обойти эту проблему?
...