首页 > 解决方案 > InMemoryUserDetailsManager updateUser 调用后未获取更新的密码

问题描述

嗨,我有一个使用 WebSecurityConfigurerAdapter 实现 HTTP 基本身份验证的 Rest WS。允许更新密码,我需要让 WS 在不重新启动服务器的情况下获取更新的密码以下是代码:

安全配置

// 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);
    }
}

将更新密码的控制器

@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);
    }
}

第一次使用凭据 admin/password 调用 updatePass() 后,我可以看到密码已在调试器中更新为“pass”

在此处输入图像描述

我假设如果我要再次调用 updatePass(),我应该使用admin/pass。然而事实证明它仍在使用旧的admin/password

我在编写此代码时参考的来源source1 source2

*我正在使用 Advance Rest Client 拨打电话

标签: javaspringrestspring-security

解决方案


我没有使用 SecurityContext,而是重写了接口 UserDetailsS​​ervice 的函数 loadUserByUsername,以让 Spring Security 始终从 DB 中获取最新的密码。


推荐阅读