【发布时间】:2015-01-15 07:23:35
【问题描述】:
通过调用获取当前用户很有名:
springSecurityService.currentUser ;
Spring Ssecurity API 是否将此对象保存在HttpSession 中。如果是,如何从 session 访问这个对象。
即:session['currentUser']
【问题讨论】:
标签: grails spring-security httpsession
通过调用获取当前用户很有名:
springSecurityService.currentUser ;
Spring Ssecurity API 是否将此对象保存在HttpSession 中。如果是,如何从 session 访问这个对象。
即:session['currentUser']
【问题讨论】:
标签: grails spring-security httpsession
没有。
正如您在回答中所示,Principal 存储在会话中,但这是由org.springframework.security.core.userdetails.UserDetailsService 创建的org.springframework.security.core.userdetails.UserDetails 实例。插件中的默认实现是grails.plugin.springsecurity.userdetails.GrailsUser,但这很容易定制。
UserDetails 实例通常是一个轻量级对象,仅包含用户名和哈希密码、一些锁定/启用的布尔值以及用于存储角色名称的 GrantedAuthority 实例集合。我经常建议用户扩展它以包含有用但在登录会话期间不太可能更改的数据,例如全名,避免去数据库检索它。由于UserDetails 存储在会话中,并且可以通过springSecurityService.principal 轻松访问,因此它是存储此类数据的好地方。
但这与从getCurrentUser()/currentUser 返回的内容不同 - 这是由UserDetailsService 加载以创建UserDetails 实例的GORM 用户/个人域类。它可以有更多与之关联的数据、延迟加载的 hasMany 集合等。它通常是一个相当大的对象,不应该存储在会话中。这样做确实可以方便地使用其数据,但会影响可伸缩性,因为您浪费了服务器内存并限制了服务器可以拥有的并发会话数。而且它是一个断开连接的 Hibernate 对象,因此要将其用于大多数与持久性相关的操作,无论如何都需要重新加载实例,通常使用merge()。这会从数据库中加载整个内容,因此在UserDetails 中存储您需要的额外数据以及实例的 ID 会更加高效,这样您就可以根据需要轻松检索实例。这就是 getCurrentUser()/currentUser 所做的 - 如果它可用于 get() 调用,它使用 id,或者使用相当于 findByUsername() 调用的用户名(如果用户名有唯一索引)。
【讨论】:
在 HttpSession 检查session.getAttributeNames() 之后,我想分享我的结果:
session.getAttribute('SPRING_SECURITY_CONTEXT').authentication.principal
【讨论】: