13

Is there ever a case for:

def user = User.get(springSecurityService.principal.id)

over

def user = springSecurityService.currentUser

All I can think of is preventing lazy inits or ensuring data you are currently operating on is not stale?

dre
  • 1,027
  • 1
  • 11
  • 31

3 Answers3

16

In practical terms, I don't see much difference between these two. I would be inclined to use

def user = springSecurityService.currentUser

Because it's slightly shorter that the other form, it's what the plugin docs recommend, and there might be some additional caching of the user within plugin (beyond the caching already provided by Hibernate).

Dónal
  • 185,044
  • 174
  • 569
  • 824
  • As of [this](https://github.com/grails-plugins/grails-spring-security-core/commit/daeeb700b7de1820efa4d2da0b1f4a81bea5adad) commit, the method `getCurrentuser()` has been deprecated. See Joshua's answer below for `getPrincipal()` which the commit linked above has as the alternative. – Cisco Jan 03 '17 at 17:34
  • @Donal: The usages of Spring Security version 2.x and 3.x are fairly different. In the version 2.x, `SpringSecurityService.getCurrentUser()` is available and will be deprecated in 3.x version. – Tung Nov 23 '17 at 11:58
  • The method `getCurrentUser` is no longer marked for deprecation. The `@deprecated` annotation has been removed from the [source code](https://github.com/grails-plugins/grails-spring-security-core/blob/master/plugin/grails-app/services/grails/plugin/springsecurity/SpringSecurityService.groovy). `getCurrentUser` is described in the [current documentation](https://grails-plugins.github.io/grails-spring-security-core/latest/#getcurrentuser). – Ders Jan 11 '21 at 16:34
7

Well, there is a slight difference between the two. The documentation points this out.

currentUser will always return the domain instance of the currently logged in user.

principal on the other hand, retrieves the currently logged in user's Principal. If authenticated, the principal will be a grails.plugin.springsecurity.userdetails.GrailsUser, unless you have created a custom UserDetailsService, in which case it will be whatever implementation of UserDetails you use there.

If not authenticated and the AnonymousAuthenticationFilter is active (true by default) then a standard org.springframework.security.core.userdetails.User is used.

Hope that helps clear things up.

thepner
  • 479
  • 3
  • 13
Joshua Moore
  • 24,706
  • 6
  • 50
  • 73
  • Sure does, but another angle on the question; is there ever a need to explicitly load the user as in the first line, rather than just retrieving through the spring service. Same thing? – dre Apr 24 '14 at 21:36
  • In the case of Domain class, it's the same thing. – Joshua Moore Apr 24 '14 at 21:40
  • I don't understand how this can be true "currentUser will *always* return the domain instance of the currently logged in user" given that a `User` domain class might not exist, i.e. if you have a custom implementation of `UserDetailsService` – Dónal Apr 24 '14 at 21:44
  • From the docs: getCurrentUser() Retrieves a domain class instance for the currently authenticated user. During authentication a user/person domain class instance is loaded to get the user's password, roles, etc. and the id of the instance is saved. This method uses the id and the domain class to re-load the instance. – Joshua Moore Apr 24 '14 at 21:46
  • But obviously this is just talking about the case where *is* a user domain class. If there is no user domain class, then obviously this method can't return an instance of it. – Dónal Apr 24 '14 at 21:48
2

We just encountered a case where code was using currentUser and failing because there was no User record for the User domain. In our case, principal.username worked because we had a custom UserDetailsService that was creating a GrailsUser on the fly if one didn't exist in the User table.

So the distinction is important.

Neal
  • 41
  • 3