Grails Spring Security (get current user)
Solution 1
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).
Solution 2
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.
Solution 3
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.
dre
Updated on June 06, 2022Comments
-
dre almost 2 years
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 about 10 yearsSure 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?
-
Joshua Moore about 10 yearsIn the case of Domain class, it's the same thing.
-
Dónal about 10 yearsI 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 ofUserDetailsService
-
Joshua Moore about 10 yearsFrom 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.
-
Dónal about 10 yearsBut 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.
-
Cisco over 7 yearsAs of this commit, the method
getCurrentuser()
has been deprecated. See Joshua's answer below forgetPrincipal()
which the commit linked above has as the alternative. -
Tung over 6 years@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. -
Ders over 3 yearsThe method
getCurrentUser
is no longer marked for deprecation. The@deprecated
annotation has been removed from the source code.getCurrentUser
is described in the current documentation.