10

目前我们有 6 个 Maven 模块:

  • webapp
  • security
  • core(提供对数据库的访问User
  • common
  • module1
  • module2

我认为依赖树非常明显:

  • webapp取决于一切
  • security取决于核心
  • core取决于共同点
  • common不依赖任何东西
  • module1取决于核心和共同点
  • module2依赖于core、module1和common

现在我想要一些BaseEntity:它应该有一个@PrePersist保存当前的User. 几乎每个实体都会使用它BaseEntity。这就是为什么每个模块都依赖于core.

而且因为一切都取决于core,所以将它BaseEntity也放在core模块中似乎是合乎逻辑的。(即使我更愿意使用common它,但由于依赖关系,这似乎是不可能的)。

现在问题出现了:要设置当前用户,我必须使用 access SecurityContextHolder.getContext().getAuthentication().getPrincipal()。但是有了这个我会有一些不必要的依赖(或者我只是太挑剔了吗?)。

如果我想要自定义实现UserDetails. 我应该把它放在哪里?core还是security?或者只是让User实体实现是很常见的UserDetails?我不这么认为。问题出现了,因为在对用户进行身份验证时,我必须在模块UserDetails内创建对象。security当我想检索当前User我必须将getPrincipal()方法转换为自定义UserDetails类。

我真的很困惑如何让事物保持松散耦合,但同时也实现了应用程序所需的一切。

我想到的最后一个想法是关于使用依赖注入,但我不知道它是否有效!?(在模块中有一个currentUserBean security,其他人可以简单地通过 获取它@Autowired MyCustomUserDetails

所以请帮助我把这些事情做好!

谢谢!:)

4

1 回答 1

0

首先,通过将方法放在单独的侦听器类中,可以将注入当前用户的代码BaseEntity放在不同的模块中(该core模块不依赖于该模块) 。@PrePersist为避免将@EntityListeners注解添加到实体类(并因此添加依赖项),您可以通过 XML 配置侦听器。看到这个答案

其次,将依赖项注入实体侦听器似乎很麻烦,如此所述。因此,我会坚持

SecurityContextHolder.getContext().getAuthentication().getPrincipal()

由于这段代码可以在security模块中,我认为这没什么大不了的。如果您担心转换为UserDetails,则可以改为调用getAuthentication().getName(),它直接返回主体的名称(如果可用)并使用它在数据库中查找当前用户。

最后,关于让Userimplement UserDetails:当然,这样做会再次增加对 Spring Security 的依赖,所以如果你想避免这种情况,那就不要这样做。否则,我看不出它有任何重大问题,除了在你的类中有你可能不需要的方法 ( isAccountNonExpired, isAccountNonLocked...) 并且User在检索主体时需要强制转换。优点是您不需要先从数据库中检索用户。

于 2021-11-18T13:29:45.930 回答