初始化受Spring身份验证保护的存储库

时间:2019-05-27 09:20:03

标签: java spring spring-boot spring-security

我使用Spring Boot Data REST将实体的Hibernate存储库映射到REST路由。我还使用Spring Security的@PreAuthorize注释来保护那些存储库的某些方法。这在生产期间可以正常工作,但是当我想以数据以编程方式初始化存储库(例如,添加第一个要开始使用的用户和一些其他示例数据)时,它会抱怨“在SecurityContext中找不到身份验证对象”。我意识到这是因为在配置数据库时(通过将对象保存到存储库的自动装配组件),安全上下文中没有经过身份验证的用户。但是,我想在配置过程中暂时避开此授权,以便初始化数据库。

有什么办法可以做到这一点?如果没有,如何手动登录初始化方法?我已经看到了第二种方法的一些尝试,但是它们都需要访问AuthenticationManager,我不知道该如何获得。

2 个答案:

答案 0 :(得分:1)

一个简单的解决方案:忽略安全性,而将注意力集中在空的存储库上

@Component
class InitializeDataIfNoDataPresent {
  private final UserRepo repository;

  public InitializeDataIfNoDataPresent(UserRepo repo) {
      this.repository = repo;
  }

  @EventListener(ApplicationReadyEvent.class)
  public void init() {
    if(0 == repository.count()) {
      setupData();
    } 
  }

  @PreAuthorize("hasRole('ADMIN')")
  public void setupData() {
    // your existing setup
  }

}

启动应用程序且您的存储库为空时,即使没有用户在场,也会调用setupData()

ref:stackoverflow-initialization-secured

答案 1 :(得分:1)

您可以使用以下代码创建具有足够权限的伪造用户,并在运行该受保护方法之前将其设置为SecurityContext

List<GrantedAuthority> grantedAuthorities = new ArrayList<>();

//Setup the permission that the user should have in order to run that method.
//It is the customized value based on your security configuration
grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_SUPER_ADMIN")); 

//Ensure this user is enabled , active and has above permission
User user = new User("admin", "password", true, true, true, true, grantedAuthorities);

Authentication auth = new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(auth);

执行该受保护的方法后,重置SecurityContext(等同于注销):

SecurityContextHolder.clearContext();