1

I'm building a REST API with Spring Boot and OAuth2 and I'm facing with troubles when trying to update the Principal object on a session. I need to do this when updating the user because some relations on the database could change and I think it's not a good option checking the user on the database for getting the values on each request.

I read a lot of posts telling that solution is only adding the new context to a SecurityContextHolder, like this:

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

    CustomUserDetails u = (CustomUserDetails)authentication.getPrincipal();
    //Change here some details from user and update the database

    SecurityContextHolder.getContext().setAuthentication(authentication);

But in my case, it doesn't work, if I make a request with the same access token, the Principal object is returning always the old values.

--- EDIT ---

My security config class:

@Configuration
@EnableWebSecurity

public class SecurityConfiguration extends WebSecurityConfigurerAdapter {


   @Autowired
   private CustomUserDetailsService customUserDetailsService;

   @Autowired
   public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {

       auth.userDetailsService(customUserDetailsService);
   }

   @Override
   @Bean
   public AuthenticationManager authenticationManagerBean() throws Exception {

       return super.authenticationManagerBean();
   }
}

And my CustomUserDetailService class:

@Service
public class CustomUserDetailsService implements UserDetailsService {


   @Resource
   public MyUserRepository usersRepository;

   @Override
   public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

       Optional<AppUser> usersOptional = usersRepository.findByEmail(username);

       usersOptional.
           orElseThrow(() -> new UsernameNotFoundException(username));

       return usersOptional
               .map(CustomUserDetails::new)
               .get();
   }
}
Mellao
  • 116
  • 1
  • 10
  • Which spring security version do you use? 5.x? – Chris Jan 31 '20 at 16:50
  • I use spring-boot-starter-security as articactId without version, so I suppose that is 2.2.4 as I can see here https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security – Mellao Feb 01 '20 at 07:44
  • And also spring-security-oauth2 which is 2.4.0 – Mellao Feb 01 '20 at 09:00
  • Looking at dependencies it seems that it uses the 5.x version. Sorry for lasts comments – Mellao Feb 01 '20 at 20:44
  • The SecurityContext and therefore the principal is created from parsing the token. What does your ```@EnableWebSecurity``` annotated config class look like? Can you update your post? – Chris Feb 02 '20 at 08:02
  • Added more code @theshadog – Mellao Feb 02 '20 at 11:32
  • Shouldn’t you revoke the updated user’s access token in order to be refreshed ? – r4phG Feb 02 '20 at 11:37
  • @r4phG If I revoke an access token, user will be forced to re-login again after update something... – Mellao Feb 02 '20 at 11:49
  • @Mellao Or make use of its refresh token that will create a brand new access token with the new values I guess – r4phG Feb 02 '20 at 12:01
  • @r4phG on this case the client should refresh the token and the idea is to be completely transparent to the user. Just updating the user and going forward... – Mellao Feb 02 '20 at 12:23
  • From oauth2 doc : OAuth 2.0 Refresh Token. The Refresh Token grant type is used by clients to exchange a refresh token for an access token when the access token has expired. This allows clients to continue to have a valid access token without further interaction with the user. – r4phG Feb 02 '20 at 12:41
  • 2
    If you force access token expiration - the refresh token would recreate a brand new access token – r4phG Feb 02 '20 at 12:42
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/207102/discussion-between-mellao-and-r4phg). – Mellao Feb 03 '20 at 12:58

1 Answers1

1

Okay, so finally I decided as @r4phG said, to expire the current token and use refresh token to get a new one, forcing retrieving the updated user.

Mellao
  • 116
  • 1
  • 10