使用spring进行身份验证期间访问受保护的存储库

时间:2018-10-22 22:42:58

标签: spring spring-security spring-data-rest

我正在开发一个基本应用程序,该应用程序应在spring数据休息的帮助下生成用于不同实体的一些标准休息端点。端点应仅对具有特定角色的用户可用(通过Spring Security)。

现在,我的用户详细信息服务从数据库加载信息,以便在身份验证期间创建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);
}

它可以工作,但是我的端点当然对所有人开放。


问题

  • 我所做的事情有根本的错误吗?
  • 如果没有,我该如何解决该问题?

0 个答案:

没有答案