弹簧安全动态授权



im 使用 Spring Security和 Spring boot 开发应用程序,使用 SecurityConf 保护我的 API im 的特定端点,如下所示:

@Override
public void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.passwordEncoder(passwordEncoder)
.withUser(username).password(password).roles(ADMIN_ROLE);
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/survey/report/**").hasRole(ADMIN_ROLE)
.and().formLogin()
.and().logout();
}

密码和用户名在启动时从数据库加载。

一切似乎都很好,但现在我必须实现一种更改管理员密码的方法,我实现了存储库、服务和控制器方法来使用新的加密密码更改数据库,但就目前而言,除非我重新启动它(这会导致类加载新的用户名和密码),否则更改不会反映在应用程序中)。

如何使应用程序从数据库中重新加载新的用户名和密码,而无需重新启动它?(在生产中,这是一个将不停止运行的应用程序)

这是密码更改方法的控制器:

@RequestMapping(value = "/change", method = RequestMethod.POST)
public ResponseEntity changePassword(@RequestBody Password password) {
return passwordService.updatePassword(password);
}

这是服务方法:

public ResponseEntity updatePassword(Password password) {
Administrator administrator = administratorRepository.findAdministrator();
if (passwordEncoder.matches(password.getOldPassword(), administrator.getPassword())) {
String encodePassword = passwordEncoder.encode(password.getNewPassword());
administrator.setPassword(encodePassword);
administratorRepository.updateAdministrator(administrator);
return new ResponseEntity(HttpStatus.OK);
}
return new ResponseEntity(HttpStatus.BAD_REQUEST);
}

编辑

我使用自动连线方法在 SecurityConfig 类的属性上加载用户名和密码,如下所示:

@Autowired
private void initUser() {
Administrator administrator = administratorRepository.findAdministrator();
this.password = administrator.getPassword();
this.username = administrator.getUsername();
}

我的类被定义为:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final String ADMIN_ROLE = "ADMIN";
private String username;
private String password;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private AdministratorRepository administratorRepository;

密码编码器是我用来加盐和散列管理员通行证的类,存储库是我保存数据的地方

像这样使用 CustomUserDetailService 而不是 AuthenticationProvider

@Component("userDetailsService")
public class CustomUserDetailsService implements org.springframework.security.core.userdetails.UserDetailsService {

private static String username;
private static String password;
private final Logger log = LoggerFactory.getLogger(CustomUserDetailsService.class);
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

return new User(CustomUserDetailsService.username,CustomUserDetailsService.password,null);
}
}

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Inject
@Qualifier("userDetailsService")
private UserDetailsService userDetailsService;
@Inject
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService);
}
@Override
public void configure(WebSecurity web) throws Exception {
}
}

,然后在 中更改密码

public ResponseEntity updatePassword(Password password) {
Administrator administrator = administratorRepository.findAdministrator();
if (passwordEncoder.matches(password.getOldPassword(), administrator.getPassword())) {
String encodePassword = passwordEncoder.encode(password.getNewPassword());
administrator.setPassword(encodePassword);
administratorRepository.updateAdministrator(administrator);
CustomUserDetailsService.password=encodePassword;
return new ResponseEntity(HttpStatus.OK);
}
return new ResponseEntity(HttpStatus.BAD_REQUEST);
}

最新更新