43

This must be a common issue... and I feel that after googling, and SOing I must have just not looked around thoroughly for the answer enough or that no1 has asked it... so please forgive me.

I am using Spring Security with Hibernate etc.

So a User/principal has logged in and made some changes to their profile.

I use my DAO to update the profile (UserDetails), and I want my Principal to automatically reflect this update.

However when I get the Principal again, I get the dirty version (from my initial login).

Does anyone know of how I can get Spring Security to reload from Hibernate the updated UserDetails?

alwinc
  • 1,317
  • 3
  • 14
  • 21
  • OK I found something that helped me http://stackoverflow.com/questions/2398224/spring-security-autowire-providermanager Getting the Provider Manager allowed me to reauthenticate. Now the problem seems to be that the new Principal has all the periphery references lazy initialized causing it to throw exceptions further down the line – alwinc Oct 25 '11 at 14:31
  • That's really more of a Hibernate / ORM strategy problem, and not so much a Spring Security problem, though... right? – Peter Mularien Oct 25 '11 at 19:51
  • 1
    Yeah I looked into it a bit more and it seems that Spring Sec makes the UserDetails immunitable for security reasons. As such, the best practice is to re-login the userdetails by forcing them to reenter their password. – alwinc Dec 09 '11 at 06:17

2 Answers2

58

OK dug around and finally found the answer.

We can create a UsernamePasswordAuthenticationToken and assign the updated Principal to the context.

Authentication authentication = new UsernamePasswordAuthenticationToken(userObject, userObject.getPassword(), userObject.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);

See also "How to manually set an authenticated user in Spring Security / SpringMVC".

Community
  • 1
  • 1
alwinc
  • 1,317
  • 3
  • 14
  • 21
  • 15
    Your solution works. I would, however, use a `PreAuthenticatedAuthenticationToken` instead of a `UsernamePasswordAuthenticationToken`. This basically does the same thing - it just helps to clarify your intent and enhances readability of your code – Stefan Haberl Nov 02 '16 at 19:40
  • 2
    This is updating the authorities in authentication object but not in principal. any idea how to update principal? – Kiran Kumar Apr 24 '18 at 13:26
  • My `userObject.getPassword()` is null (for security reasons we're unable to get the password), any way it can be done without the password? – Tom Bom Dec 23 '20 at 03:27
  • @TomBom You're allowed to pass `null` as the password. – Unmitigated Aug 01 '22 at 20:33
0

i had the same problem

i fixed it with getting the authentication from SecurityContextHolder cast it's principal to User then update principal.

everything is working but i don't know this is a good practice or not.