通过调用
springSecurityService.currentUser ;
来获得当前用户是著名的Spring Security API是否将此对象保存在
HttpSession
中。如果是这样,如何从session访问此对象。即:
session['currentUser']
最佳答案
没有。
如您在答案中所示,Principal
存储在 session 中,但这是由org.springframework.security.core.userdetails.UserDetails
创建的org.springframework.security.core.userdetails.UserDetailsService
实例。插件中默认的实现是grails.plugin.springsecurity.userdetails.GrailsUser
,但是很容易自定义。UserDetails
实例通常是一个轻量级对象,仅包含用户名和哈希密码,一些已锁定/启用的 bool(boolean) 值以及一组用于存储角色名称的GrantedAuthority
实例。我经常建议用户将其扩展为还包含有用但在登录 session 期间不太可能更改的数据,例如全名,以避免去数据库检索它。由于UserDetails
存储在 session 中,并且可以通过springSecurityService.principal
轻松访问,因此是存储此类数据的好地方。
但这与getCurrentUser()
/ currentUser
返回的内容不同-这是UserDetailsService
加载的GORM用户/人域类,用于创建UserDetails
实例。它可以具有更多与之关联的数据,延迟加载的hasMany集合等。它通常是一个相当大的对象,不应存储在 session 中。这样做确实可以方便地使用其数据,但是会影响可伸缩性,因为这会浪费服务器内存并限制服务器可以具有的并发 session 数。而且它是一个断开连接的Hibernate对象,因此要将其用于大多数与持久性相关的操作,则无论如何都需要您重新加载实例,通常使用merge()
。这会从数据库中加载整个内容,因此将所需的额外数据与实例ID一起存储在UserDetails
中的效率要高得多,因此您可以根据需要轻松地检索实例。这就是getCurrentUser()
/ currentUser
的作用-如果可用于get()
调用,它将使用id,或者使用等效于findByUsername()
调用的用户名(如果用户名具有唯一索引,则费用应大致相同)。
关于grails - Grails Spring Security插件在哪里将currentUser保存在HttpSession中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26988668/