0

Hi I have a Rest WS using WebSecurityConfigurerAdapter to implement HTTP Basic auth. The password is allowed to be updated and I need to let the WS to pick up updated password without restarting server Following are the codes:

SecurityConfig

// init a user with credentials admin/password
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                        //disable csrf
                        .csrf().disable()
                        //authentic all requests
                        .authorizeRequests().anyRequest().authenticated().and().httpBasic()
                        //disable session
                        .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(inMemoryUserDetailsManager());
    }

    @Bean
    public InMemoryUserDetailsManager inMemoryUserDetailsManager() {
        Properties users = new Properties();
        users.put("admin", "password,USER,enabled");
        return new InMemoryUserDetailsManager(users);
    }
}

The controller that will update password

@RestController
public class someController{
    @Autowired
    public InMemoryUserDetailsManager inMemoryUserDetailsManager;

    // update password from password -> pass
    @RequestMapping(...)
    public updatePass(){
        ArrayList<GrantedAuthority> grantedAuthoritiesList = new ArrayList<>();
        grantedAuthoritiesList.add(new SimpleGrantedAuthority("USER"));

        this.inMemoryUserDetailsManager.updateUser(new User("admin", "pass", grantedAuthoritiesList));
    }

    // another way that also doesn’t work
    @RequestMapping(...)
    public newUpdate(){
        ArrayList<GrantedAuthority> grantedAuthoritiesList = new ArrayList<>();
        grantedAuthoritiesList.add(new SimpleGrantedAuthority("USER"));    
        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("admin", "pass",
                        grantedAuthoritiesList);

        SecurityContext context = SecurityContextHolder.getContext();
        context.setAuthentication(auth);
        SecurityContextHolder.setContext(context);
    }
}

After calling updatePass() with credential admin/password for the first time, I can see that the password has been updated to "pass" in debugger

enter image description here

I assume that if I'm to call updatePass() again, I should use admin/pass. However it turned out to be still using the old admin/password.

Sources I referred to when writing this code source1 source2

*I'm using Advance Rest Client to make the calls

wayne
  • 598
  • 3
  • 15

2 Answers2

0

When you update the password, you have to set the UserDetails in springSecurityContext object if the user is authenticated.

Atul
  • 3,043
  • 27
  • 39
  • could you give more details regarding your answer? thanks in advance – wayne Oct 29 '19 at 09:57
  • This is the thing for which I am talking about, once you got the auth object update it;s details and set it again with new one: SecurityContext context = SecurityContextHolder.getContext(); context.setAuthentication(auth); SecurityContextHolder.setContext(context); – Atul Oct 29 '19 at 10:35
  • I followed your way and created new function newUpdate() but it's still not picking up the new pwd. Any idea what went wrong? – wayne Oct 30 '19 at 13:37
  • Whenever you update anything in UserDetails then you have to set/create it in auth object and set it into the SecurityCOntext object. – Atul Oct 31 '19 at 08:04
  • Thanks @Atul, that’s what I did in the new function newUpdate() but it still doesn’t work. Could you take a look pls? – wayne Oct 31 '19 at 12:19
  • See this, this might helps you: https://stackoverflow.com/questions/50621118/update-users-first-name-and-last-name-in-principal/50639739#50639739 – Atul Oct 31 '19 at 12:50
0

instead of using SecurityContext, I overwrote function loadUserByUsername of interface UserDetailsService to let spring security always pick up the latest pwd from DB.

wayne
  • 598
  • 3
  • 15